Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XPath square bracket operator produces unexpected result [duplicate]

Tags:

xslt

xpath

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?

like image 384
Archie Avatar asked Oct 23 '25 21:10

Archie


1 Answers

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 descendant para element; the former selects all descendant para elements that are the first para 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.

like image 163
michael.hor257k Avatar answered Oct 25 '25 15:10

michael.hor257k



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!