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个条目,这非常有效!谢谢