Who am I
Who am I

Reputation: 33

Database XPath Queries

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

Answers (1)

har07
har07

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>.

Demo 1

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 elements

Demo 2

Upvotes: 2

Related Questions