cassianoleal
cassianoleal

Reputation: 2566

How can I locate a tag via CSS selectors, referencing the content of a sibling tag?

I'm working on a Ruby script that will parse and manipulate some XML files. I'm using Nokogiri for the XML handling.

The problem I have is that there are several constructs like this one:

<USER_ELEMENT>
  <NAME>ATTRIBUTE01</NAME>
  <VALUE>XXX</VALUE>
</USER_ELEMENT>

I need to set the <VALUE> tag that's within the same of a particular <VALUE>ATTRIBUEnn</VALUE>. My current approach is using

xml.css('USER_ELEMENT').find { |node| node.at_css('NAME').text == 'ATTRIBUTEnn'}.at_css('VALUE').content = 'NEW_VALUE'

but it looks rather ugly.

I'm wondering which would be a cleaner way of dealing with the situation?

Upvotes: 1

Views: 136

Answers (3)

pguardiario
pguardiario

Reputation: 55012

The css selector for siblings is ~:

xml.at('USER_ELEMENT > NAME[text()="ATTRIBUTE01"] ~ VALUE').content = 'NEW_VALUE'

Upvotes: 2

Phrogz
Phrogz

Reputation: 303549

Using XPath:

attnn = "ATTRIBUTE01"
xml.at_xpath("//USER_ELEMENT[NAME='#{attnn}']/VALUE").content = "Yay"
puts xml
#=> <USER_ELEMENT>
#=>   <NAME>ATTRIBUTE01</NAME>
#=>   <VALUE>Yay</VALUE>
#=> </USER_ELEMENT>

In English, that XPath says:

  • //USER_ELEMENT - find elements with this name anywhere in the document
  • […] - but only if…
    • NAME="ATTRIBUTE01" - …you can find a child NAME element with this text
  • /VALUE - and now find the child VALUE elements of these

Upvotes: 3

ckyg
ckyg

Reputation: 23

I don't know if nokogiri supports CSS3, but if it does, this should work

xml.css('USER_ELEMENT NAME:content("ATTRIBUTEnn") + VALUE').content = "NEW_VALUE"

Upvotes: 0

Related Questions