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'])]