2013-03-29 109 views
1

我很抱歉,如果這已被回答,但我找不到正確的方式來得到這個工作。我正在使用Nokogiri來修改通過應用程序生成的SVG圖表,並且我遇到了一些障礙。我正在使用的代碼看起來是這樣的:包裝與Nokogiri

<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來包裝整個nodeset,但我無法弄清楚如何讓它在所有集合上工作,而不是在每個節點集上工作。任何指導將不勝感激。

謝謝!

+0

看起來你的結尾'svg'標籤缺少斜槓。 – Kelvin

回答

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代碼。

+0

感謝您的快速回復。這工作完美! –

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 } 
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標記處的斜線。

+0

請勿使用'doc.xpath('// svg')[0]'。相反,使用'at'更適合可讀性(如果你想挑剔,可以使用'at_xpath')。 –

+0

感謝您的回覆和鏈接。我肯定會參考這個向前邁進。 –