J'ai une tâche simple d'accéder aux valeurs de certains attributs. Ceci est un script simple qui utilise Nokogiri::XML::Builder
pour 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:
<?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 généré semble correct. Cependant, mes tentatives d'accès aux attributs provoquent la génération d'une erreur:
Document already has a root node
Je ne comprends pas pourquoi puts
provoquerait cette erreur.
L'utilisation de Nokogiri :: XML :: Reader fonctionne pour votre exemple, mais ce n'est probablement pas la réponse complète que vous recherchez (Notez qu'il n'y a pas de méthode attributes
pour Builder ).
reader = Nokogiri::XML::Reader(builder.to_xml)
reader.read #Moves to next node in document
reader.attribute("messageId")
Notez que si vous avez de nouveau émis reader.read
Puis essayé reader.attribute("messageId")
le résultat sera nil
car le nœud actuel 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
Voici une façon un peu plus succincte d'accéder aux attributs en utilisant Nokogiri
(en supposant que votre xml est déjà stocké dans une variable appelée xml
, comme couvert par la réponse de @atomicules):
xml.xpath("//Placement").attr("messageId")