Невозможно перебрать элементы в REXML - PullRequest
0 голосов
/ 21 июня 2011

Я использую Ruby для добавления новых элементов в выбранные узлы XML. Как это:

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 )

Это структура, которую я хочу:

<fmxmlsnippet type='FMObjectList'>
    <node/>
    <Step name='Variable'/>
    <node/>
    <Step name='Comment'/>
    <node/>
    <Step name='Variable'/>
    <node/>
</fmxmlsnippet>' 

Но это то, что я получаю с кодом выше:

<fmxmlsnippet type='FMObjectList'>
    <Step name='Variable'/>
    <Step name='Comment'/>
    <Step name='Variable'/>
    <node/>
</fmxmlsnippet>' 

Что я делаю не так?

Полагаю, это связано с моим непониманием того, как выполняется блок. Кажется, путь работает, потому что он может печатать атрибуты нужных элементов просто отлично.

Я бы хотел остаться с REXML, потому что это часть дистрибутива Ruby, но я бы рассмотрел Nokogiri, если смогу заставить его работать таким образом.

1 Ответ

2 голосов
/ 21 июня 2011

Это использует Нокогири.Я предпочитаю и рекомендую его, потому что он очень гибок и является стандартом де-факто для Ruby в наши дни.

xml = <<EOT
<fmxmlsnippet type="FMObjectList">
    <Step name="Variable"/>
    <Step name="Comment"/>
    <Step name="Variable"/>
</fmxmlsnippet>
EOT

require 'nokogiri'

doc = Nokogiri::XML(xml)

doc.search('Step[name="Variable"]').each do |s|
  s.add_previous_sibling('<node/>')
  s.add_next_sibling('<node/>')
end

puts doc.to_xml

# >> <?xml version="1.0"?>
# >> <fmxmlsnippet type="FMObjectList">
# >>     <node/><Step name="Variable"/><node/>
# >>     <Step name="Comment"/>
# >>     <node/><Step name="Variable"/><node/>
# >> </fmxmlsnippet>

Он использует средства доступа CSS для поиска Step узлов с name="Variable".Для каждого встреченного он добавляет предыдущего и следующего родного брата <node>.Nokogiri также поддерживает XPath, поэтому '//Step[@name="Variable"]' будет работать так же хорошо.

...