How to find all adjacent siblings at once with XPath
I want to find all the adjacent siblings of a node at once using a single XPath expression, if at all possible. Given the input
<a id="1"/>
<start/>
<a id="2"/>
<a id="3"/>
<b/>
<a id="4"/>
and an XPath expression similar to //start/following-sibling::a
I want to select a [2] and a [3] but not a [4] . Also, if there are any intermediate elements between start and a [2] , nothing should be selected.
source to share
The simplest one I can find is:
//start/following-sibling::a intersect //start/following-sibling::*[name()!='a'][1]/preceding-sibling::a
What it is:
- Take all the brothers
a
, following thestart
://start/following-sibling::a
. (Result: a2, a3, a4.) For now, set this to one side. - Then take the first non-sibling following
start
://start/following-sibling::*[name()!='a'][1]
(Result: b.) - And find all the nodes that precede it
a
:/preceding-sibling::a
. (Result: a1, a2, a3) - Take the intersection of 1 and 3. (Result: a2, a3)
Update: . Another way of the phrase is //start/following-sibling::*[name()!='a'][1]/preceding-sibling::a[preceding-sibling::start]
, it roughly corresponds to: take the first non-sibling following start
, set back, but just select the elements that are still preceded start
.
Update 2: If you know what b
will always be named b
, you can of course replace the rather tricky part following-sibling::*[name()!='a'][1]
with following-sibling::b[1]
.
source to share