我使用 XPather 使用不同的 XPath 查询(仅适用于较旧的 firefox 版本)并注意到以下查询的结果之间的差异
这显示了一些结果
//div[descendant::table/descendant::td[4]]
此 list 为空 list
//div[//table//td[4]]
它们是由于某些规则而不同还是只是 XPath 解释器的特定实现的不当行为? (似乎是从 FF 引擎中使用的,XPather 只是一个优秀的简单查询 GUI)
最佳答案
在XPath 1.0中,//
是/descendant-or-self::node()/
的缩写,因此您的第一个路径是/descendant-or-self::node()/div[descendant::table/descendant::td[4]]
,而第二个路径与/descendant-or-self::node()/div[/descendant-or-self::node()/table/descendant-or-self::node()/td[4]]
完全不同。因此,主要区别在于,在您的第一个谓词中,您查找相对于div
元素的后代,而在第二个谓词中,您从根节点/
(也称为文档节点)中查找后代。
您可能希望第二个路径表达式的 //div[.//table//td[4]]
更接近第一个。
[编辑]
这是一个示例:
<html>
<body>
<div>
<table>
<tbody>
<tr>
<td>1</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>4</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
对于该示例,路径
//div[descendant::table/descendant::td[4]]
选择 div
元素,因为它有一个 table
子元素,该子元素具有第四个 td
后代。然而,使用
//div[.//table//td[4]]
我们寻找 //div[./descendant-or-self::node()/table/descendant-or-self::node()/td[4]]
,它是 //div[./descendant-or-self::node()/table/descendant-or-self::node()/child::td[4]]
的缩写,并且没有具有第四个 td
子元素的元素。我希望这能解释差异,如果您使用
//div[.//table/descendant::td[4]]
那么您应该得到与原始表单相同的结果。