I also think I’m confused about XPath usage. I’m new to C# and XPath, so please be patient with me 😉
First, my XML file that I’m testing with:
<?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>
So first I want to get the “testnode” that contains a “name” I’m interested in. So I did the following, which worked correctly:
XmlNode testRoot = xmlDoc.DocumentElement.SelectSingleNode("/testroot/testnode[name=\"Test Node 1\"]");
Now I want to get all of the nodes under it that contain a “number” element. According to my reading, I should be able to do this:
XmlNodeList testNodes = testRoot.SelectNodes("number");
But that yields an empty list. The only way I got any results was to use //:
XmlNodeList testNodes = testRoot.SelectNodes("//number");
The problem is that seems to search all of the siblings and parents of the testRoot. When I print everything out I get every node in the file that contains “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
This behavior confuses me. Am I using XPaths improperly, or does it normally search from the absolute root no matter which XmlNode you start with?
You’re trying to find direct child nodes called
number. There aren’t any of those – just onethingselement. If you want descendants, say so:The version with
"//number"basically looks through all nodes in the document, hence your other result.Having said all this, if you’re using .NET 3.5 or higher I’d just use LINQ to XML and do all the querying in that. It’s a much nicer API, IMO 🙂