Xpath query to find elements which contain a certain descendant

33,815

Solution 1

"has a descendant named interestintag" is spelled .//interestintag in XPath, so the expression you are looking for is:

//table[@name='important']/tr[.//interestingtag]

Solution 2

Actually, you need to look for a descendant, not a child:

//table[@name='important']/tr[descendant::interestingtag]

Solution 3

I know this isn't what the OP was asking, but if you wanted to find an element that had a descendant with a particular attribute, you could do something like this:

//table[@name='important']/tr[.//*[@attr='value']]

Solution 4

I know it is a late answer but why not going the other way around. Finding all <interestingtag/> tags and then select the parent <tr> tag.

//interestingtag/ancestor::tr
Share:
33,815
Jeremy Stein
Author by

Jeremy Stein

Updated on July 09, 2022

Comments

  • Jeremy Stein
    Jeremy Stein almost 2 years

    I'm using Html Agility Pack to run xpath queries on a web page. I want to find the rows in a table which contain a certain interesting element. In the example below, I want to fetch the second row.

    <table name="important">
    <tr>
      <td>Stuff I'm NOT interested in</td>
    </tr>
    <tr>
      <td>Stuff I'm interested in</td>
      <td><interestingtag/></td>
      <td>More stuff I'm interested in</td>
    </tr>
    <tr>
      <td>Stuff I'm NOT interested in</td>
    </tr>
    <tr>
      <td>Stuff I'm NOT interested in</td>
    </tr>
    </table>
    

    I'm looking to do something like this:

    //table[@name='important']/tr[has a descendant named interestingtag]
    

    Except with valid xpath syntax. ;-)

    I suppose I could just find the interesting element itself and then work my way up the parent chain from the node that's returned, but it seemed like there ought to be a way to do this in one step and I'm just being dense.

  • Jeremy Stein
    Jeremy Stein about 15 years
    Excellent. That's very helpful. Sorry I can't accept two answers!
  • Shailesh
    Shailesh about 15 years
    I always find it fun how many ways there are to get the desired result in XPath. I believe //table[@name='important']//interestingtag//ancestor::tr should work too I believe.
  • Scott Baker
    Scott Baker about 15 years
    @Jeremy Stein: No problem, he beat me to it fair & square. :-)
  • Tomalak
    Tomalak almost 15 years
    +1 for using the "descendant" axis. More readable than the ".//" shorthand, IMHO.
  • Scott Baker
    Scott Baker almost 15 years
    @Tomalak: you're too kind. :-) I find it more readable as well... too easy to misplace or not see the period, IMHO.
  • Shailesh
    Shailesh almost 15 years
    +1 from me too, I am used to the ".//" form, but I also do Perl for a living ;--) so "descendant::" is probably clearer.
  • Nick A. Watts
    Nick A. Watts almost 9 years
    I believe that the descendant axis is only valid in XSLT 3.0 though (at least that's the error that Saxon gives when I tried it out). So you might be stuck with .// if you're not on XSLT 3.0 yet.
  • Suraj Shrestha
    Suraj Shrestha over 2 years
    very interesting solution