Beertastic Beertastic - 6 months ago 19
Ruby Question

Get parent node where child = x

I want to return a 'parent' node from an XML source when I find a matching child.

If I search for 'ddd':

@doc.xpath('//item[contains(., "ddd")]')


I want to return 'Section 2'

I can't find documentation on 'where' type code for Nokogiri.
Is this even possible??

<entry>
<match>
<field>Section 1</field>
<child>
<item>aaa</item>
<item>bbb</item>
<item>ccc</item>
</child>
</match>
<match>
<field>Section 2</field>
<child>
<item>ddd</item>
<item>eee</item>
<item>fff</item>
</child>
</match>
<match>
<field>Section 3</field>
<child>
<item>hhh</item>
<item>iii</item>
<item>jjj</item>
</child>
</match>
</entry>


Here's a more accurate XML format.
I'd need to go up and down the node tree to get Section 2.
Is that possible?

<entry>
<match>
<field>
<foo>Section 1</foo>
</field>
<child>
<item>aaa</item>
<item>bbb</item>
<item>ccc</item>
</child>
</match>
<match>
<field>
<foo>Section 2</foo>
</field>
<child>
<item>ddd</item>
<item>eee</item>
<item>fff</item>
</child>
</match>
<match>
<field>
<foo>Section 3</foo>
</field>
<child>
<item>hhh</item>
<item>iii</item>
<item>jjj</item>
</child>
</match>
</entry>

Answer

You can do this in XPath:

@doc.xpath("/entry/match[child/item[contains(., 'ddd')]]/field/foo")

This is using your second sample. It first finds the match elements that have child/item descendants where the item contains ddd, and then finds the foo element grandchildren of that match.

Comments