2010-05-25 17 views
49

Mam proste zadanie dostępu do wartości niektórych atrybutów. Poniżej znajduje się prosty skrypt, który używa Nokogiri::XML::Builder do utworzenia prostego dokumentu xml.Jak uzyskać dostęp do atrybutów za pomocą Nokogiri

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

Wyniki są poniżej:

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

XML, który jest generowany wygląda dobrze. Jednak próby uzyskania dostępu do atrybutów powodują wygenerowanie błędu:

Document already has a root node 

Nie rozumiem, dlaczego instrukcja puts spowodowałaby ten błąd. Wszelkie sugestie będą bardzo mile widziane.

Odpowiedz

57

Użycie Nokogiri::XML::Reader działa na Twój przykład, ale prawdopodobnie nie jest to pełna odpowiedź, której szukasz (Pamiętaj, że istnieje no attributes method for Builder).

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

Zauważ, że jeśli wydane reader.read ponownie, a następnie próbował reader.attribute("messageId") wynik będzie nil ponieważ bieżący węzeł nie będzie mieć ten atrybut.

Prawdopodobnie chcesz użyć opcji Nokogiri::XML::Document, jeśli chcesz przeszukać dokument XML według atrybutów.

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

Great Stuff , pomogło mi to o 2:22 podczas całego weekendowego codefestu. Gracias. –

+0

Szukałem tego kodu http://www.dzone.com/snippets/finding-elements-attributes i łamałem sobie głowę, ponieważ używałem @ outside [. To był prawdziwy zbawiciel. Zmarnowałem 2 dni, aby znaleźć sposób na przeanalizowanie atrybutów xml i to jest prawdziwy zbawca. Będzie miło, jeśli ten link zostanie dodany do nokogiri –

+0

możesz użyć xpath, aby uzyskać wartości atrybutów 'nokogiri_element.xpath (" @ id "). Text()' – stopanko

38

Oto nieco bardziej zwięzły sposób, aby uzyskać dostęp do atrybutów za pomocą Nokogiri (zakładając, że masz już xml przechowywane w zmiennej o nazwie xml, objętych odpowiedź @atomicules'):

xml.xpath("//Placement").attr("messageId") 
Powiązane problemy