To select all a
elements having a class
attribute of B
between some specific a
with a class
equal to A
and the next such occurrence:
/*/a[@class='A'][$n]/following-sibling::a[
@class='B' and count(preceding-sibling::a[@class='A'])=$n]
This selects everything between the nth a[@class='A']
and the next such element. For a specific example, consider the following input:
<r>
<a class="A"/>
<a class="B"/>
<a class="A"/>
<a class="B"/>
<a class="B"/>
<a class="A"/>
<a class="B"/>
<a class="B"/>
<a class="B"/>
</r>
To get the two elements between the second <a class="A"/>
and the third <a class="A"/>
:
/*/a[@class='A'][2]/following-sibling::a[
@class='B' and count(preceding-sibling::a[@class='A'])=2]
In English, this says:
Give me all of the a
elements having a class
attribute whose value is equal to B
that come after the second a
having a class attribute equal to A
and that have only two preceding siblings having a class
attribute equal to A
Similarly, and more generally, we can apply the Kayessian method for finding the intersection of two node sets. In the example given, we want the intersection of all the @class='B'
elements in 1) the set of siblings after the second <a class="A"/>
and 2) the set of siblings before the third <a class="A"/>
. The intersection of these two sets is precisely the nodes that come between those two divider elements and can be expressed like this:
/*/a[@class='A'][2]/following-sibling::a[@class='B'][
count(.|/*/a[@class='A'][3]/preceding-sibling::a[@class='B'])=
count(/*/a[@class='A'][3]/preceding-sibling::a[@class='B'])]