//p[not(ancestor::*[3])]
//table[ancestor::*[1][self::p] or ancestor::*[2][self::p]]
tr/td//a[ancestor::*[1`][self::td] or ancestor::*[2][self::td]]
答案 0 :(得分:3)
// # from the root node, look at all descendants
p[ # select nodes of type <p>, who have…
not(ancestor::*[3]) # …no ancestor 3 levels up
] #
// # from these nodes, select descendants
table[ # of type <table>, who have…
ancestor::*[1][self::p] # …a <p> as their direct ancestor
or # or
ancestor::*[2][self::p] # …a <p> as their second ancestor
] #
# syntax error, this should be a location step
tr # …select all nodes of type <tr>
/ # from their children…
td # …select all nodes of type <td>
// # from their descendants…
a[ # …select all nodes of type <a>, who have
ancestor::*[1][self::td] # …a <td> as their direct ancestor
or # or
ancestor::*[2][self::td] # …a <td> as their second ancestor
]
或者,用HTML表示:
<html>
<body>
<p>
<table>
<tr>
<td>
<a title="These would be selected." />
</td>
</tr>
</table>
</p>
</body>
</html>
无论如何,整个XPath并没有多大意义。毫无疑问,<p><table>
是无效的HTML。
答案 1 :(得分:2)
让我们打破这个:
//p[not(ancestor::*[3])]
选择所有没有第三祖先的p
标签。
在那些:
//table[ancestor::*[1][self::p] or ancestor::*[2][self::p]]
选择第一个或第二个祖先为table
标记的所有p
个标记。
然后:
tr/td//a[ancestor::*[1`][self::td] or ancestor::*[2][self::td]]
这不完全正确(开始时应该有/
)。但是,它会在tr/td//
下方选择所有a
标记,其第一个或第二个祖先是td
标记。
总而言之,在相关位置定义了一些id
属性可能会更容易实现。
答案 2 :(得分:1)
您指定的XPath表达式:
//p[not(ancestor::*[3])]
//table[ancestor::*[1][self::p] or ancestor::*[2][self::p]]
tr/td//a
在语法上不合法 - 在/
之前缺少tr
。
更正的XPath表达式:
//p[not(ancestor::*[3])]
//table[ancestor::*[1][self::p] or ancestor::*[2][self::p]]
/tr/td//a
提供了作为this问题的答案。
如链接(上述)答案中所述,含义为:
这将选择其父或祖父为td的所有元素,其父级为tr,其父级为表,其父级或祖父级是p
,其祖先少于3个 - 元素
OP想要一种方法来获取a
元素,这些元素可以位于文档根目录下不超过3层的p
下,然后在table/tr/td
下table
被隐藏在距离p
不超过3的级别。
当然,想要选择这样的节点可能看起来不太有意义,但我们无法判断任何人的需求和要求。
令人惊奇的事实是XPath非常强大,甚至无法满足这些要求。