2013-03-29 3 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> 

Я попытался с помощью такие методы, как до и после, но в этой ситуации он не будет работать правильно. В идеале я бы просто обернул весь набор узлов оболочкой, но я не могу понять, как заставить его работать во всех наборах, а не на каждом узле. Любое руководство будет высоко оценено.

Спасибо!

+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

Спасибо за ответ и ссылку. Я определенно буду ссылаться на это движение вперед. –

Смежные вопросы