Reputation: 33
I was given this XML and asked to indicate how many elements the expression returns:
<a>
<a>
<a>1</a>
<a>2</a>
</a>
<a>
<a>3</a>
<a>4</a>
</a>
</a>
The XPath queries are:
i) //a[a/text()=3]/a
ii) //a[a/a/text()=3]/a/a
iii) //a[a/text()=2][a/text()=3]
And the answers given are i) 2, ii) 4, iii) 0
However, I was having some problem when trying to understand it. For i),
What I understand is firstly I check the predicate. //a means descendant or self so that means I am checking at //a/a/3. Since I got a 3 in the path stated,
<a>
<a>
<a>3</a>
<a>4</a>
</a>
</a>
so the predicate is true. Then, I execute the XPath queries which is //a/a which will return me 2 as this block:
<a>
<a>3</a>
<a>4</a>
</a>
contains 2 inside. Then for ii), first I check the predicate //a/a/a/3, same as above I got that path. Since predicate is returning true, so I will execute the XPath query such as //a/a/a. But shouldn't it return as 1 since I am looking at this:
<a>
<a>
<a>1</a>
</a>
</a>
I am really confused on how to trace it and I am pretty sure my concept is wrong as the answer is wrong. Is there any simple way to do it or maybe some better examples?
Thanks in advance!
Upvotes: 1
Views: 628
Reputation: 89305
I'll try to explain the first XPath as an example. Test your understanding after reading this answer, by applying what you just understood to the rest of the XPath.
//a
: find all a
elements, anywhere in the document. Up to this point 7 elements would be returned.[a/text()=3]
: filter the a
elements found by the previous XPath to those having child element a
where one of the child text node equals 3
. Up to this point only one element would be returned; the parent of <a>3</a>
./a
: return child element a
from <a>3</a>
element found by the previous XPath. It means the entire XPath would return 2 elements, since there are two a
elements that is child of parent of <a>3</a>
.output :
<a>3</a>
<a>4</a>
UPDATE :
Just realized that you are confused with the 2nd XPath rather than the 1st. But your understanding about the first is also a bit off, so I expect the initial answer is still useful. Here is a brief explanation about the 2nd XPath :
//a
: find all a
elements, anywhere in the document. Up to this point 7 elements would be returned.[a/a/text()=3]
: The expression in predicate would match parent of <a>3</a>
. So the entire XPath up to this point would match only one element; the root element./a/a
: from the root element found by the previous XPath, return all grand-child a
elements. So the entire XPath returns 4 elementsUpvotes: 2