XPath: Select first element with a specific attribute

The XPath bookstore/book[1] selects the first book node under bookstore .

How can I select the first node that matches a more complicated condition, eg the first node that matches /bookstore/book[@location='US']


use (/bookstore/book[@location='US'])[1]

This will first get the book elements with the location attribute equal to 'US'. Then it will select the first node from that set. Note the use of parentheses, which are required by some implementations.

(note this is not the same as /bookstore/book[1][@location='US'] unless the first element also happens to have that location attribute )


/bookstore/book[@location='US'][1] works only with simple structure.

Add a bit more structure and things break.

With

<bookstore>
 <category>
  <book location="US">A1</book>
  <book location="FIN">A2</book>
 </category>
 <category>
  <book location="FIN">B1</book>
  <book location="US">B2</book>
 </category>
</bookstore> 

/bookstore/category/book[@location='US'][1] yields

<book location="US">A1</book>
<book location="US">B2</book>

not "the first node that matches a more complicated condition". /bookstore/category/book[@location='US'][2] returns nothing.

With parentheses you can get the result the original question was for:

(/bookstore/category/book[@location='US'])[1] gives

<book location="US">A1</book>

and (/bookstore/category/book[@location='US'])[2] works as expected.


As an explanation to Jonathan Fingland's answer:

  • multiple conditions in the same predicate ( [position()=1 and @location='US'] ) must be true as a whole
  • multiple conditions in consecutive predicates ( [position()=1][@location='US'] ) must be true one after another
  • this implies that [position()=1][@location='US'] != [@location='US'][position()=1]
    while [position()=1 and @location='US'] == [@location='US' and position()=1]
  • hint: a lone [position()=1] can be abbreviated to [1]
  • You can build complex expressions in predicates with the Boolean operators " and " and " or ", and with the Boolean XPath functions not() , true() and false() . Plus you can wrap sub-expressions in parentheses.

    链接地址: http://www.djcxy.com/p/56994.html

    上一篇: 我如何匹配包含特定字符串的属性?

    下一篇: XPath:选择具有特定属性的第一个元素