Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XPath and Selecting a single node

Tags:

.net

xpath

I'm using XPath in .NET to parse an XML document, along the lines of:

XmlNodeList lotsOStuff = doc.SelectNodes("//stuff");

foreach (XmlNode stuff in lotsOStuff) {
   XmlNode stuffChild = stuff.SelectSingleNode("//stuffChild");
   // ... etc
}

The issue is that the XPath Query for stuffChild is always returning the child of the first stuff element, never the rest. Can XPath not be used to query against an individual XMLElement?

like image 368
FlySwat Avatar asked Aug 25 '08 20:08

FlySwat


People also ask

How do you select nodes?

Click a node. On the property bar, choose Rectangular from the Selection mode list box, and drag around the nodes that you want to select. On the property bar, choose Freehand from the Selection mode list box, and drag around the nodes you want to select. Hold down Shift, and click each node.

How do I select the first child in XPath?

The key part of this XPath is *[1] , which will select the node value of the first child of Department .


3 Answers

// at the beginning of an XPath expression starts from the document root. Try ".//stuffChild". . is shorthand for self::node(), which will set the context for the search, and // is shorthand for the descendant axis.

So you have:

XmlNode stuffChild = stuff.SelectSingleNode(".//stuffChild");

which translates to:

xmlNode stuffChild = stuff.SelectSingleNode("self::node()/descendant::stuffChild");

xmlNode stuffChild = stuff.SelectSingleNode("self::node()/descendant-or-self::stuffChild");

In the case where the child node could have the same name as the parent, you would want to use the slightly more verbose syntax that follows, to ensure that you don't re-select the parent:

xmlNode stuffChild = stuff.SelectSingleNode("self::node()/descendant::stuffChild");

Also note that if "stuffChild" is a direct descendant of "stuff", you can completely omit the prefixes, and just select "stuffChild".

XmlNode stuffChild = stuff.SelectSingleNode("stuffChild");

The W3Schools tutorial has helpful info in an easy to digest format.

like image 189
Chris Marasti-Georg Avatar answered Sep 29 '22 06:09

Chris Marasti-Georg


The // you use in front of stuffChild means you're looking for stuffChild elements, starting from the root.

If you want to start from the current node (decendants of the current node), you should use .//, as in:

stuff.SelectSingleNode(".//stuffChild");
like image 40
Tom Lokhorst Avatar answered Sep 29 '22 04:09

Tom Lokhorst


If "stuffChild" is a child node of "stuff", then your xpath should just be:

XmlNode stuffChild = stuff.SelectSingleNode("stuffChild");
like image 22
Rob Thomas Avatar answered Sep 29 '22 06:09

Rob Thomas