使用XPath解析XML文档

可以说我有以下xml(一个简单的例子)

  one   two   

我试图通过使用XmlDocument和XPath解析这个(最终我可以创建行列表)。

例如…

 XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); foreach(XmlNode row in doc.SelectNodes("//row")) { string rowName = row.SelectSingleNode("//name").InnerText; } 

为什么在我的foreach循环中,rowName总是“一个”? 我希望它在第一次迭代时是“一个”,在第二次迭代时是“两个”。

似乎// name获取文档中的第一个实例,而不是我期望的行中的第一个实例。 毕竟,我在“行”节点上调用该方法。 如果这是“它是如何工作的”那么任何人都可以解释我如何改变它以满足我的需求?

谢谢

 XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); foreach(XmlNode row in doc.SelectNodes("//row")) { var rowName = row.SelectSingleNode("name"); } 

您发布的代码实际上是否正确? 我在row.SelectNode()上遇到编译错误,因为它不是XmlNode的成员。

无论如何,我上面的示例有效,但假设节点中只有一个节点,因此如果不是这样,您可能需要使用SelectNodes()而不是SelectSingleNode()

正如其他人所示,使用.InnerText来获取值。

使用LINQ to XML。 包括using System.Xml.Linq; 在您的代码文件中,然后执行以下代码以获取列表

 XDocument xDoc = XDocument.Load(filepath); IEnumerable xNames; xNames = xDoc.Descendants("name"); 

这将为您提供名称元素的列表。 然后,如果要将其转换为List只需执行以下操作:

 List list = new List(); foreach (XElement element in xNames) { list.Add(element.value); } 

你的第二个xpath以//开头。 这是/descendant-or-self::node()的缩写,你可以看到它以/开头,这意味着它从文档的根目录搜索,无论你使用它的上下文。

你可能想要一个:

 var rowName = row.SelectSingleNode("name"); 

找到该row 直接子节点的name节点,或

 var rowName = row.SelectSingleNode(".//name"); 

在行下the任何位置查找name节点* . Note the . Note the第二个xpath中. Note the .`,它导致xpath从上下文节点开始。

使用相对路径,例如string rowName = row.SelectSingleNode("name").InnerText;

问题出在你的第二个XPath查询中:

 //row 

这具有全局范围,因此无论您从何处调用它,它都将选择所有 row元素。

如果用以下代码替换表达式,它应该有效:

 .//row 

我会使用SelectSingleNode,然后使用InnerText属性。

 var rowName = row.SelectSingleNode("name").InnerText; 

使用以下内容

  doc.LoadXml(xml); foreach(XmlNode row in doc.SelectNodes("/rows/row")) { string rowName = row.SelectSingleNode("//name").InnerText.ToString(); }