使用XPath解析XML文档

本文关键字:文档 XML 解析 XPath 使用 | 更新日期: 2023-09-27 18:16:03

假设我有以下xml(一个快速示例)

<rows>
   <row>
      <name>one</name>
   </row>
   <row>
      <name>two</name>
   </row>
</rows>

我试图通过使用XmlDocument和XPath来解析这个(最终,我可以制作一个行列表)。

例如…

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

为什么在我的foreach循环中,rowName总是"one"?我希望它在第一次迭代时是"1",在第二次迭代时是"2"。

似乎//name获取文档中的第一个实例,而不是我所期望的行中的第一个实例。毕竟,我是在"row"节点上调用该方法的。如果这就是"它的工作方式",那么谁能解释一下我如何改变它来满足我的需求?

谢谢

使用XPath解析XML文档

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

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

无论如何,我上面的例子是有效的,但假设在<row>节点中只有一个<name>节点,所以如果不是这种情况,您可能需要使用SelectNodes()而不是SelectSingleNode()

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

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

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

将为您提供一个name元素列表。然后,如果你想把它变成List<string>,只需这样做:

List<string> list = new List<string>();
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");

查找name节点*在the. 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();
            }