I’m using Ruby to inject new elements around selected XML nodes. Like this:
require 'rexml/document'
include REXML
xml = <<EOF
<fmxmlsnippet type="FMObjectList">
<Step name="Variable"/>
<Step name="Comment"/>
<Step name="Variable"/>
</fmxmlsnippet>
EOF
doc = Document.new xml
el = Element.new 'node'
doc.elements.each( "//Step[@name=\"Variable\"]"){ |e|
e.previous_sibling = el
e.next_sibling = el
}
doc.write( $stdout, 2 )
This is the structure that I want:
<fmxmlsnippet type='FMObjectList'>
<node/>
<Step name='Variable'/>
<node/>
<Step name='Comment'/>
<node/>
<Step name='Variable'/>
<node/>
</fmxmlsnippet>'
But this is what I’m getting with the code above:
<fmxmlsnippet type='FMObjectList'>
<Step name='Variable'/>
<Step name='Comment'/>
<Step name='Variable'/>
<node/>
</fmxmlsnippet>'
What am I doing wrong?
I’m guessing it has to do with my lack of understanding of how the block is getting executed. The path seems to work because it can print the desired elements’ attributes just fine.
I’d like to stay with REXML because it’s part of the Ruby distribution, but I’d consider Nokogiri if I can get it working that way.
This is using Nokogiri. I prefer and recommend it because it’s very flexible and the defacto standard for Ruby these days.
It’s using CSS accessors to find the
Stepnodes withname="Variable". For each one encountered it adds a previous and next sibling<node>. Nokogiri supports XPath also so'//Step[@name="Variable"]'would work just as well.