使用 XPath 查找最热门的以下元素



在XPath中,我知道我可以使用/following::*选择所有以下元素,但是我想避免选择任何后续元素中包含的子元素。

例如,给定此文档:

<body>
<div id="div1">
<p id="p1">...</p>
<p id="p2">
<span id="span1"></span>
<span id="span2"><i id="i1">...</i></span>
</p>
<p id="p3">...</p>
</div>
<div id="div2">
<p id="p4">...</p>
<p id="p5">...</p>
</div>
</body>

如果我选择了span1,我想选择span2(但不是i1)、p3div2(但不是p4p5)。

在 Python 中,我的代码可能如下所示:

>>> lxml.html.fromstring(document).xpath('//*[@id="span1"]/following::*')
[<Element span at 0x1082bd680>,
<Element i at 0x1082bd4f0>,
<Element p at 0x1082bd770>,
<Element div at 0x1082bd360>,
<Element p at 0x1082bd7c0>,
<Element p at 0x1082bdef0>]

但我想返回的是:

[<Element span at 0x1082bd680>,
<Element p at 0x1082bd770>,
<Element div at 0x1082bd360>]
>编辑:@kjhughes答案让我完成了90%的路程。由于现实生活中的示例可能没有可以轻松用于匹配的 ID,因此我最终编写了如下代码:
find_following = lxml.html.etree.XPath(
"following::*[not(../preceding::*[. = node()])]"
)

这个XPath,

//*[@id="span1"]/following::*[not(../preceding::*[@id="span1"])]

选择目标元素后面的元素span其父元素没有目标span元素作为前置元素,

<span id="span2"><i id="i1">...</i></span>
<p id="p3">...</p>
<div id="div2"> <p id="p4">...</p> <p id="p5">...</p> </div>

根据要求。

XPath 3.1 具有以下outermost()函数:outermost(following::*)选择所有后续元素,不包括节点集中另一个元素的后代。

XPath 2.0 允许following::* except following::*/descendant::*.

在 XPath 1.0 中,您可以将($A except $B)表示为$A[count(.|$B)=count($B)]。(尽管这并不是那么有用,因为 XPath 本身无法绑定变量)。

最新更新