56 votes

Comment accéder aux attributs avec Nokogiri

J'ai une tâche simple d'accéder à des valeurs de certains attributs. Ci-dessous est un simple script qui utilise Nokogiri::XML::Builder créer un simple document xml.

require 'nokogiri'

builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
  xml.Placement(:messageId => "392847-039820-938777", :system => "MOD", :version => "2.0") {
    xml.objects {
        xml.object(:myattribute => "99", :anotherattrib => "333")
        xml.nextobject_ '9387toot'
        xml.Entertainment "Last Man Standing"
    }
  }
end

puts builder.to_xml
puts builder.root.attributes["messageId"]

Les résultats sont ci-dessous:

<?xml version="1.0" encoding="UTF-8"?>
<Placement messageId="392847-039820-938777" version="2.0" system="MOD">
  <objects>
    <object anotherattrib="333" myattribute="99"/>
    <nextobject>9387toot</nextobject>
    <Entertainment>Last Man Standing</Entertainment>
  </objects>
</Placement>
C:/Ruby/lib/ruby/gems/1.8/gems/nokogiri-1.4.2-x86-mingw32/lib/nokogiri/xml/document.rb:178:in `add_child': Document already has a root node (RuntimeError)
    from C:/Ruby/lib/ruby/gems/1.8/gems/nokogiri-1.4.2-x86-mingw32/lib/nokogiri/xml/node.rb:455:in `parent='
    from C:/Ruby/lib/ruby/gems/1.8/gems/nokogiri-1.4.2-x86-mingw32/lib/nokogiri/xml/builder.rb:358:in `insert'
    from C:/Ruby/lib/ruby/gems/1.8/gems/nokogiri-1.4.2-x86-mingw32/lib/nokogiri/xml/builder.rb:350:in `method_missing'
    from C:/Documents and Settings/etrojan/workspace/Lads/tryXPATH2.rb:15

Le XML est généré à l'air bien. Cependant, mes tentatives pour accéder aux attributs de provoquer une erreur sera générée

Document already has a root node

Je ne comprends pas pourquoi un met déclaration serait la cause de cette erreur. Toutes les suggestions sont grandement appréciés.

68voto

atomicules Points 1065

À l'aide de Nokogiri::XML::Reader fonctionne pour votre exemple, mais n'est probablement pas la réponse que vous cherchez (Notez qu'il n'est pas d' attributes méthode pour le Constructeur).

reader = Nokogiri::XML::Reader(builder.to_xml)
reader.read #Moves to next node in document
reader.attribute("messageId")

Notez que si vous émises reader.read , puis à nouveau tenté reader.attribute("messageId") le résultat sera nil depuis le nœud courant n'aura pas cet attribut.

Ce que vous voulez probablement à faire est d'utiliser Nokogiri::XML::Document si vous souhaitez rechercher un document XML par attribut.

doc = Nokogiri::XML(builder.to_xml)
elems = doc.xpath("//*[@messageId]") #get all elements with an attribute of 'messageId'
elems[0].attr('messageId') #gets value of attribute of first elem 

51voto

ben.snape Points 595

Voici un moyen légèrement plus succinct d’accéder aux attributs en utilisant Nokogiri (en supposant que votre fichier XML soit déjà stocké dans une variable appelée xml , comme indiqué dans la réponse de @atomicules):

 xml.xpath("//Placement").attr("messageId")
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X