如果已经回答,我道歉,但我找不到正确的方法让这个工作。我正在使用Nokogiri修改通过应用程序生成的SVG图表,我遇到了一些障碍。我正在使用的代码看起来像这样:
<svg>
<g id="1">
<text>lorem</text>
<text>ipsum</text>
</g>
<g id="2">
<text>lorem</text>
<text>ipsum</text>
</g>
<g id="3">
<text>lorem</text>
<text>ipsum</text>
</g>
<svg>
我希望将这个附加到每个文档中,因为它是由脚本分析的:
<svg>
<g id="scale" transform="scale(1.0)">
<g id="1">
<text>lorem</text>
<text>ipsum</text>
</g>
<g id="2">
<text>lorem</text>
<text>ipsum</text>
</g>
<g id="3">
<text>lorem</text>
<text>ipsum</text>
</g>
</g>
<svg>
我尝试过使用之前和之后的方法,但在这种情况下它无法正常工作。理想情况下,我只是用wrap包装整个节点集,但我无法弄清楚如何让它在所有集合而不是每个节点集上工作。任何指导都将非常感谢。
谢谢!
答案 0 :(得分:1)
我是这样做的:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<svg>
<g id="1">
<text>lorem</text>
<text>ipsum</text>
</g>
<g id="2">
<text>lorem</text>
<text>ipsum</text>
</g>
<g id="3">
<text>lorem</text>
<text>ipsum</text>
</g>
</svg>
EOT
svg = doc.at('svg')
svg.children = '<g id="scale" transform="scale(1.0)">' + svg.children.to_xml + '</g>'
puts svg.to_xml
运行输出:
<svg>
<g id="scale" transform="scale(1.0)">
<g id="1">
<text>lorem</text>
<text>ipsum</text>
</g>
<g id="2">
<text>lorem</text>
<text>ipsum</text>
</g>
<g id="3">
<text>lorem</text>
<text>ipsum</text>
</g>
</g>
</svg>
Nokogiri很好地让我们将节点定义为字符串,并将它们强制转换为XML::Node
个对象。给它一个包含XML的字符串,然后将它转换为NodeSet,这样我们就可以干净利落地操作XML DOM,而无需编写u-gly代码。
答案 1 :(得分:0)
doc = Nokogiri.XML( raw_svg )
wrapper_g = doc.create_element('g', 'id' => "scale", 'transform' => "scale(1.0)")
doc.xpath('/svg/g').each {|elem| wrapper_g << elem }
doc.root << wrapper_g
可选 - 删除空文本节点:
doc.xpath('//text()').each {|t| t.text =~ /\A\s*\z/ and t.remove }
答案 2 :(得分:0)
cheat sheet可能会有所帮助。
require 'nokogiri'
doc = Nokogiri::XML(%Q{
<svg>
<g id="1">
<text>lorem</text>
<text>ipsum</text>
</g>
<g id="2">
<text>lorem</text>
<text>ipsum</text>
</g>
<g id="3">
<text>lorem</text>
<text>ipsum</text>
</g>
</svg>
})
svg = doc.xpath('//svg')[0]
wrapper = doc.create_element('g', 'id' => 'scale', 'transform' => 'scale(1.0)')
wrapper.children = svg.children
svg.add_child wrapper
puts doc
请注意,您在结束svg
代码时错过了斜杠。