Introduction:
If I run an inner XPath query, I get text nodes that are not related to the context of the outer XPath query (the previous received node). Does this mean that XPathNavigator always have the whole tree available so it does not respect the current context? Does it mean that query is always executed againts the root? Please see the example below:
This is the example of book.xml:
<bookstore>
<book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
<title>The Autobiography of Benjamin Franklin</title>
<author>
<first-name>Benjamin</first-name>
<last-name>Franklin</last-name>
</author>
<price>8.99</price>
</book>
<book genre="novel" publicationdate="1967-11-17" ISBN="0-201-63361-2">
<title>The Confidence Man</title>
<author>
<first-name>Herman</first-name>
<last-name>Melville</last-name>
</author>
<price>11.99</price>
</book>
<book genre="philosophy" publicationdate="1991-02-15" ISBN="1-861001-57-6">
<title>The Gorgias</title>
<author>
<name>Plato</name>
</author>
<price>9.99</price>
</book>
</bookstore>
XPath queries:
I would expect that If I run the second query (inner one) in the context of the first one, I would not get any results. However I was wrong.
Tested code:
var xpath1 = "/bookstore/book/title";
var xpath2 = "/bookstore/book/author/first-name/text()";
var xDocument = new XPathDocument(new StreamReader("./book.xml"));
var navigator = xDocument.CreateNavigator();
navigator.MoveToChild(XPathNodeType.Element);
var iterator = navigator.Select(xpath1) as XPathNodeIterator;
while (iterator?.MoveNext() ?? false)
{
var result = iterator.Current.Evaluate(xpath2) as XPathNodeIterator;
while (result?.MoveNext() ?? false)
{
Console.WriteLine(result.Current.Value);
}
}
The result I got:
The xpath1
returns 3 nodes, resp. iterator has 3 elements because the <title>
is obviously in the XML document for the three times. Then I would expect that subsequent query xpath2
will return no data since I am in context of the <title>
node. However, it seems this is not the case. And on the output I got 3x the Benjamin Herman
.
Question:
How did I get
<first-name>
text values in the results even though I ran the query in the context of the<title>
node? Does it mean thatXPathNavigator
always performs over the entire tree?
No, XPathNavigator
will not take an absolute XPath such as
/bookstore/book/author/first-name/text()
and apply it relatively. If you want to reach author
etc when the context node is title
, then use
../author/first-name/text()
or
following-sibling::author/first-name/text()