【发布时间】:2010-11-03 15:00:51
【问题描述】:
XPath bookstore/book[1] 选择bookstore 下的第一个书节点。
如何选择第一个匹配更复杂条件的节点,例如第一个匹配/bookstore/book[@location='US']的节点
【问题讨论】:
标签: xpath
XPath bookstore/book[1] 选择bookstore 下的第一个书节点。
如何选择第一个匹配更复杂条件的节点,例如第一个匹配/bookstore/book[@location='US']的节点
【问题讨论】:
标签: xpath
用途:
(/bookstore/book[@location='US'])[1]
这将首先获取 location 属性等于“US”的 book 元素。然后它将从该集合中选择第一个节点。请注意括号的使用,这是某些实现所必需的。
注意,这与/bookstore/book[1][@location='US'] 不同,除非第一个元素也恰好具有该位置属性。
【讨论】:
/bookstore/book[@location='US'][1] 不会返回来自“美国”的所有书籍。我已经在不同语言的 xpath 实现下对其进行了多次测试。 /bookstore/book[@location='US'][1] 返回书店下的第一本“美国”书。如果有多个书店,那么它将返回每个书店的第一个。这是 OP 要求的(书店下的第一个节点)。您的版本仅返回所有书店中的一本书(第一场比赛)。
作为对 Jonathan Fingland 回答的解释:
[position()=1 and @location='US']) 中的多个条件必须为真作为一个整体
[position()=1][@location='US']) 中的多个条件必须为真一个接一个
[position()=1][@location='US'] != [@location='US'][position()=1][position()=1 and @location='US'] == [@location='US' and position()=1]
[position()=1]可以缩写为[1]
您可以使用布尔运算符“and”和“or”以及布尔 XPath 函数 not()、true() 和 false() 在谓词中构建复杂的表达式。另外,您可以将子表达式括在括号中。
【讨论】:
= 运算符可以解决问题:[position() = (1,3,5,6,7,9)]。
/bookstore/book[@location='US'][1] 仅适用于简单结构。
添加更多结构,事情就会中断。
有-
<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] 产量
<book location="US">A1</book>
<book location="US">B2</book>
不是“匹配更复杂条件的第一个节点”。 /bookstore/category/book[@location='US'][2] 不返回任何内容。
使用括号,您可以获得原始问题的结果:
(/bookstore/category/book[@location='US'])[1] 给了
<book location="US">A1</book>
(/bookstore/category/book[@location='US'])[2] 按预期工作。
【讨论】:
/bookstore/book[1] 而不是(/bookstore/book)[1]。您提供的案例与 OP 要求的案例不同。据推测,OP 接受了我的回答,因为它符合他的预期(和要求)。
'(//div[text() = "'+ name +'"])[1]/following-sibling::*/div/text()'。如果有很多节点匹配name。
找到第一个英文书节点(在整个文档中)的最简单方法,考虑到更复杂的结构化 xml 文件,例如:
<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 表达式:
/descendant::book[@location='US'][1]
【讨论】:
<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>
鉴于以上情况;你可以选择第一本书
(//book[@location='US'])[1]
这将在任何具有美国位置的地方找到第一个。 [A1]
//book[@location='US']
将返回包含位置为 US 的所有书籍的节点集。 [A1,B1,C2]
(//category/book[@location='US'])[1]
将返回存在于文档任何位置的类别中的第一个图书位置 US。 [B1]
(/bookstore//book[@location='US'])[1]
将返回存在于根元素 bookstore 下任何位置的第一本位置为 US 的书;确实使 /bookstore 部分变得多余。 [A1]
直接回答:
/bookstore/book[@location='US'][1]
将为您返回位于书店 [A1] 下的位置为 US 的 book 元素的第一个节点
顺便说一句,如果你想,在这个例子中找到第一本不是书店直系子的美国书:
(/bookstore/*//book[@location='US'])[1]
【讨论】:
例如。
<input b="demo">
和
(input[@b='demo'])[1]
【讨论】:
在在线 xpath tester 的帮助下,我正在写这个答案...
为此:
<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:
id("t2") / tbody / tr / td[1]
输出:
123
foo
bar
xyz
由于 1 表示选择所有 td 元素,它们是其直接父级的第一个子元素。
但是下面的xpath:
(id("t2") / tbody / tr / td)[1]
输出:
123
【讨论】:
如果 xpath 复杂或存在多个具有相同 xpath 的节点,则使用索引获取所需的节点。
例如:
(//bookstore[@location = 'US'])[index]
你可以给你想要的节点编号。
【讨论】:
如果给定的 xml 上提供了命名空间,最好使用它。
(/*[local-name() ='bookstore']/*[local-name()='book'][@location='US'])[1]
【讨论】: