使用Nokogiri我想将节点<inserted_node>
插入以下XML-snipplet
<foo>
<bar>some text</bar>
</foo>
像那样
<foo>
<inserted_node>
<bar>some text</bar>
</inserted_node>
</foo>.
如何通过Nokogiri实现这一目标?
答案 0 :(得分:4)
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>"
答案 1 :(得分:2)
我这样做:
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。