In XPath, I know I can select all following elements with /following::*, however I'd like to avoid also selecting the children contained within any following elements.
For example, given this document:
<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>
If I have span1 selected, I would like to select span2 (but not i1), p3, and div2 (but not p4 or p5).
In Python, my code might look something like:
>>> 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>]
But what I'd like to have returned is:
[<Element span at 0x1082bd680>,
<Element p at 0x1082bd770>,
<Element div at 0x1082bd360>]
EDIT: @kjhughes answer got me 90% of the way there. Because the real life example might not have a ID that I can easily use to match, I ended up writing code like:
find_following = lxml.html.etree.XPath(
"following::*[not(../preceding::*[. = node()])]"
)