SelectSingleNode似乎搜索父母和兄弟姐妹

时间:2011-01-28 20:33:42

标签: c# .net xml xpath

我也觉得我对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开始?

1 个答案:

答案 0 :(得分:7)

您正在尝试查找名为number直接子节点。没有任何 - 只有一个things元素。如果你想要后代,请说:

XmlNodeList testNodes = testRoot.SelectNodes("descendant::number");

带有"//number"的版本基本上会查看文档中的所有节点,因此会显示其他结果。

说完这一切之后,如果您使用的是.NET 3.5或更高版本,我只需使用LINQ to XML并进行所有查询。这是一个更好的API,IMO:)