2013-03-29 3 views
1

Je m'excuse si cela a été répondu, mais je ne peux pas trouver la bonne façon de le faire fonctionner. J'utilise Nokogiri pour modifier les diagrammes SVG qui sont générés par une application et je rencontre un petit problème. Le code que je travaille avec ressemble à ceci:Emballage avec 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> 

Je voudrais avoir cette annexe à chaque document tel qu'il est analysé par le script:

<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> 

J'ai essayé d'utiliser des méthodes telles que avant et après, mais cela ne fonctionnera pas correctement dans cette situation. Idéalement, je ne ferais que boucler l'intégralité de l'ensemble de nœuds avec le retour à la ligne, mais je n'arrive pas à comprendre comment le faire fonctionner sur tous les ensembles plutôt que sur tous les nœuds. Toute orientation serait très appréciée.

Merci!

+0

Il semble que vos balises 'svg' de fermeture manquent la barre oblique. – Kelvin

Répondre

1

Voilà comment je le ferais:

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 

Course à sorties:

<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 nous permet de bien définir les noeuds sous forme de chaînes, et les objets XML::Node à contraint. Donnez-lui une chaîne contenant XML et il la convertira en un NodeSet, afin que nous puissions manipuler clairement et clairement le DOM XML sans avoir à écrire du code u-gly.

+0

Merci pour la réponse rapide. Cela a fonctionné parfaitement! –

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 

en option - supprimer des nœuds de texte vides:

doc.xpath('//text()').each {|t| t.text =~ /\A\s*\z/ and t.remove } 
0

Le cheat sheet pourrait aider.

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 

Notez que vous avez manqué la barre oblique à la balise de fermeture svg.

+0

N'utilisez pas 'doc.xpath ('// svg') [0]'. Au lieu de cela, utilisez 'at ', ce qui est préférable pour la lisibilité (ou' at_xpath' si vous voulez être difficile). –

+0

Merci pour la réponse et le lien. Je vais certainement faire référence à ce progrès. –