我有以下HTML
<html>
[snip]
<table>
[snip]
<tr><td>One</td><td>1-1</td></tr>
[snip]
</table>
[snip]
<table>
[snip]
<tr><td>One</td><td>1-1-1</td></tr>
[snip]
</table>
</html>
..我正在尝试使用以下xpath获取值“1-1-1”
//tr[td[1] = 'One'][2]/td[2]
我将其描述为从包含至少一个td元素的第二个tr元素中检索第二个td元素值,其中第一个td元素值为“One”。我尝试了position()=last()
之类的各种改动,但无济于事。
我只知道父行的第一个单元格中第二次出现的文本“One”标识了我可以从第二个单元格中提取文本的行...所以硬编码的东西不起作用(例如//table[2]/tr[1]/td[2]
)。
有人可以告诉我为什么上面的xpath不起作用?我查看了w3c网站,发现了xpaths:
child::*[self::chapter or self::appendix][position()=last()]
描述为:
选择上下文节点的最后一章或附录子项
..这与我正在尝试做的类似,但也许不允许嵌套..
答案 0 :(得分:2)
简短回答
使用:
(//tr[td[1]='One'])[2]/td[2]
<强>解释强>
我将其描述为从第二个检索第二个td元素值 包含至少一个td元素的tr元素,其中第一个td 元素值是'一'。
//tr[td[1]='One'][2]
实际选择的是所有tr
元素,其中第一个td
子元素值为One
,而元素是第二个tr
元素//tr[td[1]='One'][2]
他们的父母。
为什么呢?这个表达式:
/descendant-or-self::node()/child::tr[td[1]='One'][2]
......相当于:
[2]
这样写,更容易看到(/descendant-or-self::node()/child::tr[td[1]='One'])[2]
比你原先想象的更早适用。添加括号:
tr
...让我们首先选择所有td
元素,其中第一个One
子元素的值为{{1}} ,然后从中获取第二个节点组。