Consider this XML document:
<foo>
<bar id="aaa"/>
<jam>
<bar id="bbb"/>
</jam>
</foo>
I am trying to find the first <bar>
element in the document.
Here's what I've discovered:
Test# | XPath Expression | Evaluation Expression | Result |
---|---|---|---|
1 | //bar |
@id |
aaa , bbb |
2 | //bar[1] |
@id |
aaa , bbb |
3 | (//bar)[1] |
@id |
aaa |
What I don't understand is why Test #2 returns aaa
, bbb
instead of just aaa
. It's as if the [1]
operator is not working.
My understanding was that in Test #2, the //bar
expression would find both nodes, and then the [1]
operator would choose the first one. Obviously, I'm missing something.
This seems to be confirmed by Test #3 which is apparently how to express what I really want.
Also, if you change the XML document to this:
<foo>
<bar id="aaa"/>
<bar id="bbb"/>
</foo>
then you get what I was expecting to see:
Test# | XPath Expression | Evaluation Expression | Result |
---|---|---|---|
1 | //bar |
@id |
aaa , bbb |
2 | //bar[1] |
@id |
aaa |
3 | (//bar)[1] |
@id |
aaa |
What subtlety am I missing here about how [1]
is supposed to work?
The XPath specification contains this note regarding the //
abbreviated syntax:
Note:
The path expression//para[1
] does not mean the same as the path expression/descendant::para[1]
. The latter selects the first descendantpara
element; the former selects all descendantpara
elements that are the firstpara
children of their respective parents.
IOW, if you want to select the first bar
element in the document you need to use:
/descendant::bar[1]
instead of:
//bar[1]
Unlike the other answers, I am not claiming it makes sense.