如何使用Nokogiri访问属性

64

我有一个简单的任务,需要访问一些属性的值。这是一个使用 Nokogiri::XML::Builder 创建简单 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文件看起来很好。然而,我的尝试访问属性导致了一个错误:

生成的XML文件看起来很好。然而,我的尝试访问属性导致了一个错误:

Document already has a root node
我不理解为什么puts会导致这个错误。
2个回答

71

使用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,因为当前节点不具有此属性。

您可能想要使用Nokogiri::XML::Document来按属性搜索XML文档。

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 

5
很棒的东西,这在一个整个周末都在编程的凌晨2:22帮了我很大的忙。谢谢。 - Chuck Bergeron
我查看了这段代码http://www.dzone.com/snippets/finding-elements-attributes,因为我在方括号外使用了@符号而感到困惑。这真的是一个救星。我浪费了两天的时间来找出解析xml属性的方法,这真是一个救星。如果将此链接添加到nokogiri中会很好。 - user1572930
你可以使用XPath获取属性值 nokogiri_element.xpath("@id").text() - stopanko
使用doc.at_xpath可以实现与elems[0]相同的效果。doc.at_xpath("//*[@messageId]")['messageId']会更简单。 - the Tin Man

55

这是使用 Nokogiri 更加简洁的方式访问属性(假设您已经将xml存储在名为xml的变量中,如@atomicules的答案所述):

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接