我也觉得我对XPath的使用感到困惑。我是C#和XPath的新手,所以请耐心等待我;)
首先,我正在测试的XML文件:
<?xml version="1.0" encoding="ISO-8859-1"?>
<testroot>
<testnode>
<name>Test Node 1</name>
<things>
<thing>
<number>One</number>
</thing>
<thing>
<number>Two</number>
</thing>
</things>
</testnode>
<testnode>
<name>Test Node 2</name>
<things>
<thing>
<number>Three</number>
</thing>
<thing>
<number>Four</number>
</thing>
</things>
</testnode>
<testnode>
<name>Test Node 3</name>
<things>
<thing>
<number>Five</number>
</thing>
</things>
</testnode>
</testroot>
首先,我想获得包含我感兴趣的“名称”的“testnode”。所以我做了以下工作,这些工作正常:
XmlNode testRoot = xmlDoc.DocumentElement.SelectSingleNode("/testroot/testnode[name=\"Test Node 1\"]");
现在我希望获得包含“number”元素的所有节点。根据我的阅读,我应该能够做到这一点:
XmlNodeList testNodes = testRoot.SelectNodes("number");
但是这会产生一个空列表。我得到任何结果的唯一方法是使用//:
XmlNodeList testNodes = testRoot.SelectNodes("//number");
问题是,似乎搜索testRoot的所有兄弟姐妹和父母。当我打印出所有内容时,我得到文件中包含“number”的每个节点:
txtOutput.InnerHtml += "<p>" + testRoot.FirstChild.InnerText + "</p>";
foreach (XmlNode node in testNodes)
{
txtOutput.InnerHtml += node.InnerText + "<br />";
}
Test Node 1 One Two Three Four Five
这种行为让我感到困惑。我是不正确地使用XPath,还是通常从绝对根搜索无论你从哪个XmlNode开始?
答案 0 :(得分:7)
您正在尝试查找名为number
的直接子节点。没有任何 - 只有一个things
元素。如果你想要后代,请说:
XmlNodeList testNodes = testRoot.SelectNodes("descendant::number");
带有"//number"
的版本基本上会查看文档中的所有节点,因此会显示其他结果。
说完这一切之后,如果您使用的是.NET 3.5或更高版本,我只需使用LINQ to XML并进行所有查询。这是一个更好的API,IMO:)