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

XPath: Select first element with a specific attribute

xpath bookstore/book[1]选择bookstore下的第一个book节点。

如何选择与更复杂条件匹配的第一个节点,例如与/bookstore/book[@location='US']匹配的第一个节点


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

这将首先获得location属性等于"us"的book元素。然后它将从该集合中选择第一个节点。注意括号的使用,这是一些实现所必需的。

(注意,这与/bookstore/book[1][@location='US']不同,除非第一个元素也具有该位置属性)


/bookstore/book[@location='US'][1]只适用于结构简单的情况。

再增加一点结构,事情就会破裂。

1
2
3
4
5
6
7
8
9
10
<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]产量

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

不是"匹配更复杂条件的第一个节点"。/bookstore/category/book[@location='US'][2]什么也不返回。

使用括号,您可以得到原始问题的结果:

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

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

(/bookstore/category/book[@location='US'])[2]的工作与预期一致。


作为对乔纳森·芬格兰答案的解释:

  • 同一谓词([position()=1 and @location='US']中的多个条件)必须整体为真
  • 连续谓词([position()=1][@location='US']中的多个条件)必须逐个为真。
  • 这意味着[position()=1][@location='US']!=EDCOX1〔5〕而[position()=1 and @location='US']==[@location='US' and position()=1]
  • 提示:一个单独的[position()=1]可以缩写为[1]

您可以使用布尔运算符"EDOCX1"(10)和"EDOCX1"(11)以及布尔xpath函数not()true()false()在谓词中构建复杂表达式。此外,还可以将子表达式括在括号中。


找到第一个英文图书节点(在整个文档中)的最简单方法,考虑到更复杂的结构化XML文件,例如:

1
2
3
4
5
6
7
8
9
10
<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>

是xpath表达式:

1
/descendant::book[@location='US'][1]

1
2
3
4
5
6
7
8
9
10
11
    <bookstore>
     <book location="US">A1</book>
     <category>
      <book location="US">B1</book>
      <book location="FIN">B2</book>
     </category>
     <section>
      <book location="FIN">C1</book>
      <book location="US">C2</book>
     </section>
    </bookstore>

因此,鉴于上述情况,您可以选择第一本书

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

这将找到第一个在任何地方有我们位置的。[A1]

1
//book[@location='US']

将返回包含所有书籍和位置us的节点集。[A1,B1,C2]

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

将返回文档中任何类别中存在的第一个图书位置us。[B1]

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

将返回第一本书,其中包含根元素bookstore下任何位置的位置us;使/bookstore部分实际上是多余的。[A1]

直接回答:

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

将返回Book元素的第一个节点,其中位于Bookbook[A1]下的位置US

顺便说一句,如果你想,在这个例子中找到第一本不是书店直接子图书的美国图书:

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

如果xpath复杂或存在多个具有相同xpath的节点,则使用索引获取所需的节点。

例如:(//书店[@location='us'])[索引]

您可以给出所需节点的编号。


为Ex.

1
<input b="demo">

1
(input[@b='demo'])[1]


借助于一个在线的XPath测试仪,我正在写这个答案…
为此:

1
2
3
4
5
6
<table id="t2"><tbody>
<tr><td>123</td><td>other</td></tr>
<tr><td>foo</td><td>columns</td></tr>
<tr><td>bar</td><td>are</td></tr>
<tr><td>xyz</td><td>ignored</td></tr>
</tbody></table>

下列xpath:

1
id("t2") / tbody / tr / td[1]

输出:

1
2
3
4
123
foo
bar
xyz

因为1意味着选择所有的td元素,它们是自己的直接父元素的第一个子元素。
但下面的xpath:

1
(id("t2") / tbody / tr / td)[1]

输出:

1
123