Home > other >  Need Xpath to target table cell node as long as cell above it contains certain text
Need Xpath to target table cell node as long as cell above it contains certain text

Time:06-01

So I have a basic table structured:

<tbody>
  <tr>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
  </tr>
</tbody> etc....

I'm trying to target a link <a> element in one cell only if the cell above it does or does not contain a word. For example:

<tbody>
  <tr>
    <td></td>
    <td><b>Fire Sale!</b></td>
  </tr>
  <tr>
    <td></td>
    <td><a href="something">linktext</a></td>
  </tr>
/tbody>

So I'd want to target the <a> only if the cell above it contains "Fire Sale!" or perhaps does not contain a word, I have scenarios both ways.

The problem is no matter what I do I can't keep the conditional axes to find the cell right above, another <a> next to (<td> immediately above) the <a> we want is also targeted e.g.

<tbody>
  <tr>
    <td></td>
    <td><b>Fire Sale!</b></td>
  </tr>
  <tr>
    <td><a href="somethingelse">link I don't want</a></td>
    <td><a href="something">linktext</a></td>
  </tr>
/tbody>

I've tried stuff like:

//tr/td/b/a[@href]/ancestor::tbody/tr/td/b[contains(text(),'Fire Sale!')]

But no matter what, because of the odd relationship between tr and td I always end up getting an affirmative conditional. That is, they share the same ancestor tree structure for the most part and targeting back down to the <td> above my main target seems impossible. Is there some way to use variables or I feel count() might help but I'm just not sure of the syntax for the whole thing.

Any ideas?

EDIT: Here is the real HTML

<table border="0" width="100%" style="border-collapse: collapse">
    <tr>
        <td width="33%" valign="top" height="225" align="center"><img border="0" src="" width="296" height="225"></td>
        <td width="33%" valign="top" height="225" align="center"><br><br><br><br><b>Unassigned</b></td>
        <td width="33%" valign="top" height="225" align="center"></td>
    </tr>
    <tr>
        <td width="33%" valign="top" height="30" align="center"><b><a href="">AAAAA</a></b><br>
                <b>XXXXXXX</b><br><b><font color="#FF0000">YYYYYYYYY</font><br></b><br></td>
        <td width="33%" valign="top" height="30" align="center"><b><a href="">BBBBB</a><br></b><br></td>
        <td width="33%" valign="top" height="30" align="center"></td>
    </tr>
    <tr>
        <td width="100%" colspan="4" height="80" align="center">
        | <a href=""> Home</a> |<br>
        | <a href="">Design</a> 
        | <a href="">Styles</a> 
        | <a href="">X Listings</a> 
        | <a href="">Y Listings</a> |<br>
        | <a href="">About the Author</a> |</td>
    </tr>
    <tr>
        <td width="100%" colspan="4" height="60" align="center">
        Copyright Some Dude, 2020<br>
        Email: <a href="">[email protected]</a></td>
    </tr>
</table>

So basically I want the link containing BBBBB only if the word 'Unassigned' does not appear above it. Or vice-versa.

CodePudding user response:

Try this one to select link from table row next to table row with cell Fire Sale! if preceding cell has no text

//tr[td='Fire Sale!']/following-sibling::tr[1]/td[preceding-sibling::td[not(normalize-space(.))]]/a

CodePudding user response:

You might first get the tbody/tr/td/b that contains Fire Sale! and then navigate to the next tr through the ancestor tr.

Note that in your expression this part //tr/td/b/a[@href] would not match as there is no anchor wrapped in a b tag in the example data.

//tbody/tr/td/b[contains(text(),'Fire Sale!')]/ancestor::tr/following-sibling::tr[1]/td/a[@href]
  • Related