tags:

views:

52

answers:

1

Hello,

From this piece of HTML:

<tbody>
    <tr>
    <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">
<tbody>

I´m trying to get an xPath expression to return all tr[@class='first'] nodes followed by tr which don´t have a "first" class, including the first node. In this case a set with tr ids 1, 2, 3 and tr with ids 4, 5, 6.

I´ve tried using:

//tbody/tr[@class='first']/self::* | following-sibling::tr[not(starts-with(@class, 'first'))]

With no success. Any thoughts on this?

Thanks

A: 

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 trs 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' trs, then march through its siblings until I find 'last' tr. Maybe someone else knows of a better way to do this.

Welbog
Thanks, I´ll give it a go using position() and some PHP instead
steaktartar