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.

+3


source to share


2 answers


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 the start

    : //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]

.

+4


source


there is no way to test it, but //start/following-sibling::*[1][self::a]

must return the closest next sibling, but only if it is "a"



0


source







All Articles