C# XDocument。Linq转换为XML。数据计数始终为零,在某些情况下返回错误结果

C# XDocument。Linq转换为XML。数据计数始终为零,在某些情况下返回错误结果,c#,.net,xml,C#,.net,Xml,可能重复: 我有一个xml: <?xml version="1.0" encoding="UTF-8"?> <string xmlns="http://tempuri.org/"> <Global> <Items> <Item text="Main text" key="1"> <Item text="Some text" key="1.1"/> <Item te

可能重复:

我有一个xml:

<?xml version="1.0" encoding="UTF-8"?>
<string xmlns="http://tempuri.org/">
<Global>
   <Items>
      <Item text="Main text" key="1">
         <Item text="Some text" key="1.1"/>
         <Item text="Other text" key="1.2"/>
         <Item text="Text" key="1.3"/>
      </Item>
      <Item text="Main text 2" key="2">
         <Item text="Some text" key="2.1"/>
         <Item text="Other text" key="2.2"/>
         <Item text="Text" key="2.3"/>
      </Item>
   </Items>
</Global>
</string>

我需要在项目中获取项目(如键2.1、1.1等)

我有以下代码:

var xml = GetXmlFromWeb(service.ServiceLink, true);
                var stringXml = new StringReader(xml); // Load data from web)
                XmlReaderSettings settings = new XmlReaderSettings();
                settings.IgnoreWhitespace = true;
                var reader = XmlTextReader.Create(stringXml, settings);

                XDocument docWithDecode = XDocument.Load(reader);
                IEnumerable<XElement> elements = docWithDecode.Root.Descendants("Item");
var xml=GetXmlFromWeb(service.ServiceLink,true);
var stringXml=新的StringReader(xml);//从web加载数据)
XmlReaderSettings设置=新建XmlReaderSettings();
settings.IgnoreWhitespace=true;
var reader=XmlTextReader.Create(stringXml,设置);
XDocument docWithDecode=XDocument.Load(读卡器);
IEnumerable elements=docWithDecode.Root.substands(“项”);
结果我得到了Count=0

这很有趣,如果我写
IEnumerable elements=docWithDecode.Root.subjects()我得到了元素,但是结构看起来很混乱,数据被复制,每个项都有名称空间引用等。所以这里有点不对劲

有人能帮我写工作代码吗?谢谢

xns=”http://tempuri.org/";
XNamespace ns = "http://tempuri.org/";
IEnumerable<XElement> elements = docWithDecode.Root.Descendants(ns+"Item");
IEnumerable elements=docWithDecode.Root.substands(ns+“Item”);
正如我在评论中提到的,L.B.在他的回答中提到的,您的
.Count()
==0问题是由于缺少名称空间。请看我在上面的链接,以更详细地解释它,但实际上您的问题是您正在搜索一个元素调用“Item”,但实际上您实际上试图找到的是namespace+“Item”。您只需要将名称空间添加到查询中

在重新阅读您的问题之后,我注意到您的XML和查询有一个问题。您有一个节点,其中有几个同名的子节点。如果使用
子体()
,将选择全部8个,而不是问题中指定的6个

要仅选择子
节点,您需要修改查询,因为
子体()
将选择匹配的任何内容。实际上,您需要使用
.Elements()
扩展方法并专门选择每个级别

XNamespace ns = "http://tempuri.org/";
IEnumerable<XElement> elements = docWithDecode.Root
                                              .Elements(ns + "Global")
                                              .Elements(ns + "Items")
                                              .Elements(ns + "Item")
                                              .Elements(ns + "Item");
xns=”http://tempuri.org/";
IEnumerable elements=docWithDecode.Root
.要素(ns+“全球”)
.要素(ns+项目)
.要素(ns+“项目”)
.要素(ns+“项目”);

您还可以使用
子体(ns+“Items”)
而不是查询中的前2个
元素()
,因为它本身不会重复。

首先,不要使用
根.subjects()
,这将返回所有子级的
IEnumerable
,并且不会保留树结构。 无论XElement子元素在树中的位置如何,它都会对其进行相同的处理。 您应该始终尝试使用
Root.Elements(ns+“InnerElementName”)
,这也将返回一个
IEnumerable
,但仅针对根的子级(不针对子级:))

使用
子体(“项”)
接收0个元素的原因是缺少命名空间。 确保添加名称空间,如果XML中有名称空间,根据我的经验,如果不添加元素名,使用元素名将无法工作

此代码将遍历您提供的结构中的XML文件:

XNamespace ns = docWithDecode.Root.Name.Namespace;
XElement xGlobal = docWithDecode.Root.Element(ns + "Global");
forach (XElement xItems in xGlobal.Elements(ns + "Items")
{
   XAttribute outerItemText = xItems.Attribute("text");
   XAttribute outerItemKey = xItems.Attribute("key");

   foreach (XElement xItem in xItems.Elements(ns + "Item"))
   {
      XAttribute innerItemText = xItem.Attribute("text");
      XAttribute innerItemKey = xItem.Attribute("key");
   }
}

我没有调试这个(我在这台计算机上没有VS),所以如果它不起作用,请告诉我,但我想你会明白的。

可能的副本你可以显示你尝试过的,因为它是正确的。我将名称空间添加到查询中,
elements
有8个条目,这非常有效!谢谢