使用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"节点上调用该方法的。如果这就是"它的工作方式",那么谁能解释一下我如何改变它来满足我的需求?
谢谢
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();
}