XML键值对C#

XML键值对C#,c#,xml,soap,C#,Xml,Soap,这是我的XDocument <grantitem adnidtype="306" xmlns="http://tempuri.org/"> <attribute key="AccountNumber" value="1111" /> <attribute key="DateofMeterRead" value="20161226" /> <attribute key="Arrears" value="11.11"

这是我的XDocument

   <grantitem adnidtype="306" xmlns="http://tempuri.org/">
      <attribute key="AccountNumber" value="1111" />
      <attribute key="DateofMeterRead" value="20161226" />
      <attribute key="Arrears" value="11.11" />
      <attribute key="MeterRead" value="11111" />
    </grantitem>

但是它返回一个空值。有人能看到一些遗漏吗?

这里有几个问题:

  • 您试图在没有命名空间的情况下获取名为
    grantitem
    的元素,而您的元素实际上在
    http://tempuri.org/
  • 您正在尝试检索属性,就像它们是元素一样。您需要检索
    grantitem
    属性
    子元素,然后检索这些元素的键/值属性
下面是一个示例,它可以满足您的需要:

using System;
using System.Linq;
using System.Xml.Linq;

class Test
{
    static void Main()
    {
        var doc = XDocument.Load("test.xml");
        XNamespace ns = "http://tempuri.org/";
        var query = doc
            .Descendants(ns + "grantitem")
            .Elements(ns + "attribute")
            .Select(x => new { 
                Key = (string) x.Attribute("key") ?? "",
                Value = (string) x.Attribute("value") ?? ""
            });

        foreach (var item in query)
        {
            Console.WriteLine(item);
        }
    }
}

您可以考虑使用创建<代码> KyValuePaule<代码>值,而不是使用匿名类型。


注意,这是为了能够在文档中的任何位置找到多个
grantitem
元素。如果实际情况是总是有一个
grantitem
元素,并且它总是根元素,那么我可能会使用
doc.root.Elements(ns+“attribute”)
而不是首先使用
子元素

  • 您试图在没有命名空间的情况下获取名为
    grantitem
    的元素,而您的元素实际上在
    http://tempuri.org/
  • 您正在尝试检索属性,就像它们是元素一样。您需要检索
    grantitem
    属性
    子元素,然后检索这些元素的键/值属性
下面是一个示例,它可以满足您的需要:

using System;
using System.Linq;
using System.Xml.Linq;

class Test
{
    static void Main()
    {
        var doc = XDocument.Load("test.xml");
        XNamespace ns = "http://tempuri.org/";
        var query = doc
            .Descendants(ns + "grantitem")
            .Elements(ns + "attribute")
            .Select(x => new { 
                Key = (string) x.Attribute("key") ?? "",
                Value = (string) x.Attribute("value") ?? ""
            });

        foreach (var item in query)
        {
            Console.WriteLine(item);
        }
    }
}

您可以考虑使用创建<代码> KyValuePaule<代码>值,而不是使用匿名类型。


注意,这是为了能够在文档中的任何位置找到多个
grantitem
元素。如果实际情况是总是有一个
grantitem
元素,而它总是根元素,我可能会使用
doc.root.Elements(ns+“attribute”)
而不是先使用
子体

我喜欢用字典做这件事:

Dictionary<string,string> dict = from b in doc.Descendants("grantitem").FirstOrDefault().Elements("attribute").GroupBy(x => (string)x.Attribute("key"), y => (string)y.Attribute("value"))
   .ToDictionary(x => x.Key, y => y.FirstOrDefault());
Dictionary dict=from b in doc.subjections(“grantitem”).FirstOrDefault().Elements(“属性”).GroupBy(x=>(string)x.attribute(“key”),y=>(string)y.attribute(“value”))
.ToDictionary(x=>x.Key,y=>y.FirstOrDefault());

我喜欢用字典做这件事:

Dictionary<string,string> dict = from b in doc.Descendants("grantitem").FirstOrDefault().Elements("attribute").GroupBy(x => (string)x.Attribute("key"), y => (string)y.Attribute("value"))
   .ToDictionary(x => x.Key, y => y.FirstOrDefault());
Dictionary dict=from b in doc.subjections(“grantitem”).FirstOrDefault().Elements(“属性”).GroupBy(x=>(string)x.attribute(“key”),y=>(string)y.attribute(“value”))
.ToDictionary(x=>x.Key,y=>y.FirstOrDefault());

您可以直接转到
属性
而不是
grantitem
@DavidG:只有在OP没有任何其他名为
属性
的元素在同一命名空间中的情况下。如果文档只是这个,我可能只选择
doc.Root.Elements(ns+“attribute”)
。但是,考虑到原始查询的结构,它可能最终成为更大文档的一部分。我将在答案中添加一些类似的内容。您可以直接转到
attribute
,而不是
grantitem
@DavidG:前提是OP在同一命名空间中没有任何其他名为
attribute
的元素。如果文档只是这个,我可能只选择
doc.Root.Elements(ns+“attribute”)
。但是,考虑到原始查询的结构,它可能最终成为更大文档的一部分。我将在答案中添加一些类似的内容。