使用Nokogiri,我想将节点<inserted_node>
插入以下XML snipplet-
<foo>
<bar>some text</bar>
</foo>
就像
<foo>
<inserted_node>
<bar>some text</bar>
</inserted_node>
</foo>.
野村怎么能做到这一点?
Nokogiri有一个方便地称为wrap
的方法。
doc.search("bar").wrap("<inserted_node>")
doc.to_html
=> <foo>
<inserted_node><bar>some text</bar></inserted_node>
</foo>
回答以下问题:
str = "<foo><bar1></bar1><bar2></bar2></foo>"
doc = Nokogiri::XML(str)
doc.search("bar1,bar2").map(&:parent).uniq.each do |node|
# Create a new element to attach the children to
inserted = doc.create_element("inserted")
# Move the children into the new element
inserted.children = node.children
# Add the new element as a child of the parent node
node << inserted
end
=> "<foo><inserted><bar1></bar1><bar2></bar2></inserted></foo>"
我会这样做:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<foo>
<bar>some text</bar>
</foo>
EOT
children = doc.root.children
doc.root.children = '<inserted_node>'
doc.at('inserted_node').children = children
puts doc.to_xml
# >> <?xml version="1.0"?>
# >> <foo>
# >> <inserted_node>
# >> <bar>some text</bar>
# >> </inserted_node>
# >> </foo>
如果有更多的内容,它仍然可以正常工作:
<foo>
<bar>some text</bar>
<baz>some more text</baz>
</foo>
再次运行:
doc = Nokogiri::XML(<<EOT)
<foo>
<bar>some text</bar>
<baz>some more text</baz>
</foo>
EOT
children = doc.root.children
doc.root.children = '<inserted_node>'
doc.at('inserted_node').children = children
puts doc.to_xml
# >> <?xml version="1.0"?>
# >> <foo>
# >> <inserted_node>
# >> <bar>some text</bar>
# >> <baz>some more text</baz>
# >> </inserted_node>
# >> </foo>
如果您想在DOM中做得更远:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<foo>
<sub_foo>
<bar>some text</bar>
<baz>some more text</baz>
</sub_foo>
</foo>
EOT
NODE_TO_INSERT = 'inserted_node'
graft_node = doc.at('sub_foo')
children = graft_node.children
graft_node.children = "<#{ NODE_TO_INSERT }>"
doc.at(NODE_TO_INSERT).children = children
puts doc.to_xml
# >> <?xml version="1.0"?>
# >> <foo>
# >> <sub_foo><inserted_node>
# >> <bar>some text</bar>
# >> <baz>some more text</baz>
# >> </inserted_node></sub_foo>
# >> </foo>
其想法是,通过获取该节点,可以指出要修改文档的位置。我使用doc.at('sub_foo')
是因为只有一个。如果有多个位置要操作,那么可以使用search
,然后对生成的NodeSet进行迭代。一旦知道要处理的节点,就抓住它的子节点并将它们记住在变量中,更改移植点下的子节点,然后将旧的子节点重新插入该节点下。
一旦你明白了这一点,你就可以很容易地破坏XML和HTML。