在XDocument中查找元素?

我有一个简单的XML

<AllBands> <Band> <Beatles ID="1234" started="1962">greatest Band<![CDATA[lalala]]></Beatles> <Last>1</Last> <Salary>2</Salary> </Band> <Band> <Doors ID="222" started="1968">regular Band<![CDATA[lalala]]></Doors> <Last>1</Last> <Salary>2</Salary> </Band> </AllBands> 

但是,

当我想要达到“门带”并更改其ID:

  using (var stream = new StringReader(result)) { XDocument xmlFile = XDocument.Load(stream); var query = from c in xmlFile.Elements("Band") select c; ... 

query 没有结果

如果我写xmlFile.Elements().Elements("Band")所以它find它。

问题是什么 ?

根需要完整的path吗?

如果是这样,为什么它没有指定AllBands

XDocument导航是否要求我知道完整级别的结构到所需的元素?

Elements()只会检查直接子Elements()在第一种情况下是根元素),在第二种情况下是根元素的子元素,因此在第二种情况下会得到匹配。 如果你只是想要任何匹配的后代使用Descendants()来代替:

 var query = from c in xmlFile.Descendants("Band") select c; 

另外,我build议你重新构build你的Xml:乐队名称应该是一个属性或元素值,而不是元素名称本身 – 这使查询(和模式validation的事情)更难,即这样的事情:

 <Band> <BandProperties Name ="Doors" ID="222" started="1968" /> <Description>regular Band<![CDATA[lalala]]></Description> <Last>1</Last> <Salary>2</Salary> </Band> 

你应该使用Root来引用根元素:

 xmlFile.Root.Elements("Band") 

如果你想在文档的任何地方find元素,可以使用Descendants代替:

 xmlFile.Descendants("Band") 

你可以这样做:

 xml.Descendants().SingleOrDefault(p => p.Name.LocalName == "Name of the node to find") 

其中xml是一个XDocument。

请注意,属性Name返回一个具有LocalName和Namespace的对象。 这就是为什么你必须使用Name.LocalName如果你想比较名称。

问题是Elements只需要你直接调用它的直接子元素。 如果你想要所有的后代,使用Descendants方法:

 var query = from c in xmlFile.Descendants("Band") 

Elements()方法返回包含当前节点的所有子元素的IEnumerable<XElement> 。 对于XDocument,该集合只包含Root元素。 因此需要以下内容:

 var query = from c in xmlFile.Root.Elements("Band") select c; 

我处理大型和复杂XML文件的经验是,有时元素和后代似乎都不能检索特定的元素(我仍然不知道为什么)。

在这种情况下,我发现更安全的select是手动search元素,如以下MSDN文章所述:

https://social.msdn.microsoft.com/Forums/vstudio/en-US/3d457c3b-292c-49e1-9fd4-9b6a950f9010/how-to-get-tag-name-of-xml-by-using-xdocument?论坛= csharpgeneral

总之,你可以创build一个GetElement函数:

 private XElement GetElement(XDocument doc,string elementName) { foreach (XNode node in doc.DescendantNodes()) { if (node is XElement) { XElement element = (XElement)node; if (element.Name.LocalName.Equals(elementName)) return element; } } return null; } 

你可以这样调用:

 XElement element = GetElement(doc,"IPHONE"); 

请注意,如果没有find匹配的元素,这将返回null