Reputation: 2566
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
Reputation: 55012
The css selector for siblings is ~:
xml.at('USER_ELEMENT > NAME[text()="ATTRIBUTE01"] ~ VALUE').content = 'NEW_VALUE'
Upvotes: 2
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
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