While it's not exactly what you want, this expression will return all nodes between a first and last class, but it won't group them together. That's the best you'll be able to do with just one XPath expression.
Given an input like this,
<tbody>
<tr id="0" class=""/>
<tr id="1" class="first"/>
<tr id="2" class=""/>
<tr id="3" class="last"/>
<tr id="4" class="first"/>
<tr id="5" class=""/>
<tr id="6" class="last"/>
<tr id="7" class=""/>
</tbody>
This XPath expression,
/tbody/tr[
(following-sibling::tr[@class='last'] and preceding-sibling::tr[@class='first'])
or @class='first' or @class='last'
]
Will return these nodes:
<tr id="1" class="first" />
<tr id="2" class="" />
<tr id="3" class="last" />
<tr id="4" class="first" />
<tr id="5" class="" />
<tr id="6" class="last" />
The expression works by checking all tr
elements whose preceding sibling is a 'first' and whose following sibling is a 'last'. That way it will exclude tr
s outside of those.
However, it does not do any grouping. I do not know of any way to do that kind of grouping with a single XPath expression. If I had to do it, I would have one XPath expression return all 'first' tr
s, then march through its siblings until I find 'last' tr
. Maybe someone else knows of a better way to do this.