0

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を検討したいと思います。

4

1 に答える 1

2

こちらはノコギリを使用。非常に柔軟で、最近の 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>

Stepでノードを見つけるために CSS アクセサーを使用していname="Variable"ます。遭遇したそれぞれについて、前の兄弟と次の兄弟を追加します<node>。Nokogiri は XPath もサポートしているため'//Step[@name="Variable"]'、同様に機能します。

于 2011-06-21T05:27:15.333 に答える