与Nokogiri一起包装

时间:2013-03-29 18:04:22

标签: ruby svg nokogiri

如果已经回答,我道歉,但我找不到正确的方法让这个工作。我正在使用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包装整个节点集,但我无法弄清楚如何让它在所有集合而不是每个节点集上工作。任何指导都将非常感谢。

谢谢!

3 个答案:

答案 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代码时错过了斜杠。