Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select a only first matching node in XPath

Tags:

xpath

I have the following XML:

<parent>
   <pet>
      <data>
         <birthday/>
      </data>
   </pet>
   <pet>
      <data>
         <birthday/>
      </data>
   </pet>
</parent> 

And now I want to select the first birthday element via parent//birthday[1] but this returns both birthday elements because bothof them are the first child of their parents.

How can I only select the first birthday element of the entire document no matter where it is located. I've tried parent//birthday[position()=1] but that doesn't work either.

like image 265
Benjamin Avatar asked Jan 29 '10 15:01

Benjamin


People also ask

How do I select the first child in XPath?

The key part of this XPath is *[1] , which will select the node value of the first child of Department . If you need the name of the node, then you will want to use this... Save this answer.

How do you select the second element with the same XPath?

For example if both text fields have //input[@id='something'] then you can edit the first field xpath as (//input[@id='something'])[1] and the second field's xpath as (//input[@id='something'])[2] in object repository.

How do I ignore the first element in XPath?

You need to wrap the expression that selects the a in parenthesis to group them in a node-set, then apply the predicate filter on position. That will find all a elements except the first one (since there is no a preceding the first one).

What does node () do in XPath?

node() matches any node (the least specific node test of them all) text() matches text nodes only. comment() matches comment nodes. * matches any element node.


1 Answers

You mean (note the parentheses!)

(/parent/pet/data/birthday)[1]

or, a shorter, but less specific variation:

(/*/*/*/birthday)[1]
(//birthday)[1]

or, more semantic, the "birthday of the first pet":

/parent/pet[1]/data/birthday

or, if not all pets have birthday entries, the "birthday of the first pet that for which a birthday is set":

/parent/pet[data/birthday][1]/data/birthday

If you work from a context node, you can abbreviate the expression by making it relative to that context node.

Explanation:

  • /parent/pet/data/birthday[1] selects all <birthday> nodes that are the first in their respective parents (the <data> nodes), throughout the document
  • (/parent/pet/data/birthday)[1] selects all <birthday> nodes, and of those (that's what the parentheses do, they create an intermediary node-set), it takes the first one
like image 88
Tomalak Avatar answered Oct 08 '22 00:10

Tomalak