xmlxpathgroovygpath

Find XML node with a specific child using GPath


I am looking for a GPath expression to find a node with a specific child.

<table>
   <tr>
      <td name="line">1</td>
      <td name="price">10</td>
   </tr>
   <tr>
      <td name="line">2</td>
      <td name="price">95</td>
   </tr>
   <tr>
      <td name="line">3</td>
      <td name="price">43</td>
   </tr>
</table>

In the example XML above, I would like to retrive the entire tr element that contains a td element with attribute price and text 95.

In XPath I would be writing something like this:

//tr[td[@name='price' and text()='95']]

The code I tried and that worked looked like this...

xmlDoc.tr.td.find { node -> node.text() == '1' }.parent()

...but that would be more of an XPath equivalent like his:

//tr/td[@name='price' and .='95']/parent::*

In this exact scenario it would do, but I am not a huge fan of the parent axe. Suppose there would be a lot more child node levels, how would I go about "nested" predicates? Return a node which has a child which has child...?

Many thanks!


Solution

  • You could use the tr as the root for the find, and use the depth first property ** to search the whole subtree

    xmlDoc.tr.find { tr -> tr.'**'.find { it.name() == 'td' && it.text() == '1' } }