Possible Duplicate:
Use Linq to Xml with Xml namespaces
我有一个 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>
我需要获取 Item 内的项目(例如使用键 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");
结果我得到 Count = 0。
这很有趣,如果我写 IEnumerable<XElement> elements = docWithDecode.Root.Descendants();
我得到了元素,但结构看起来很困惑,数据重复,每个项目都有命名空间引用等。所以这里出了问题。
有人可以帮我编写工作代码吗?谢谢!
最佳答案
正如我在评论和 L.B.在他的回答中提到,你的 .Count()
== 0 问题是由于缺少命名空间造成的。请参阅this answer我上面链接的内容是为了更详细地解释它,但实际上你的问题是你正在搜索一个名为“Item”的元素,但实际上你真正想要找到的是 namespace +“Item”。您只需将命名空间添加到查询中即可。
重新阅读您的问题后,我刚刚注意到您的 XML 和查询存在问题。您有一个节点,其中有多个同名的子节点。如果您使用Descendants()
,您将选择全部 8 个,而不是您在问题中指定的 6 个。
仅选择子项 <Item>
节点,您需要修改您的查询,因为 Descendants()
将选择任何匹配的内容。您实际上需要使用 .Elements()
扩展方法并具体选择每个级别。
XNamespace ns = "http://tempuri.org/";
IEnumerable<XElement> elements = docWithDecode.Root
.Elements(ns + "Global")
.Elements(ns + "Items")
.Elements(ns + "Item")
.Elements(ns + "Item");
您还可以使用Descendants(ns + "Items")
而不是前 2 个 Elements()
在查询中,因为它不会在自身内部重复。
关于c# - X文档。 Linq 到 XML。数据计数始终为零,在某些情况下返回错误结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10739180/