如何使用Nokogiri访问属性

我有一个简单的任务来访问一些属性的值。 下面是一个简单的脚本,它使用Nokogiri::XML::Builder创build一个简单的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"] 

结果如下:

 <?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看起来很好。 但是,我尝试访问属性会导致生成错误

 Document already has a root node 

我不明白为什么一个put语句会导致这个错误。 任何build议将不胜感激。

使用Nokogiri :: XML :: Reader适用于您的示例,但可能不是您正在查找的完整答案(请注意, Builder没有attributes方法 )。

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

请注意,如果您再次发布reader.read ,然后尝试reader.attribute("messageId")则结果将nil因为当前节点将不具有此属性。

如果你想通过属性searchXML文档,你可能要做的就是使用Nokogiri :: XML :: Document 。

 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 

下面是使用Nokogiri访问属性的略微更简洁的方法(假设您已经将xml存储在一个名为xml的variables中,如@atomicules的答案所覆盖):

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