如何使用 Nokogiri 访问属性

Posted

技术标签:

【中文标题】如何使用 Nokogiri 访问属性【英文标题】:How to access attributes using Nokogiri 【发布时间】:2011-02-23 11:32:17 【问题描述】:

我有一个访问某些属性值的简单任务。这是一个简单的脚本,它使用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/e***/workspace/Lads/tryXPATH2.rb:15

生成的 XML 看起来不错。但是,我尝试访问属性会导致生成错误:

Document already has a root node

我不明白为什么puts 会导致这个错误。

【问题讨论】:

【参考方案1】:

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

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

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

如果您想按属性搜索 XML 文档,您可能想要做的是使用 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 

【讨论】:

很棒的东西,这在整个周末的 codefest 中的凌晨 2:22 帮助了我。格拉西亚斯。 我看了@这个代码dzone.com/snippets/finding-elements-attributes 并且因为我在外面使用@而打破了我的头[。这是一个真正的救世主。我浪费了 2 天时间来找出一种解析 xml 属性的方法,这是一个真正的救星。如果此链接添加到 nokogiri 会很好 可以使用xpath获取属性值nokogiri_element.xpath("@id").text() 使用doc.at_xpath 可以达到与elems[0] 相同的效果。 doc.at_xpath("//*[@messageId]")['messageId'] 会更简单。【参考方案2】:

这是一种使用Nokogiri 访问属性的稍微简洁的方法(假设您已经将xml 存储在一个名为xml 的变量中,正如@atomicules 的回答所涵盖的那样):

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

【讨论】:

以上是关于如何使用 Nokogiri 访问属性的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Nokogiri 删除节点?

使用 nokogiri 去除样式属性

如何使用 Nokogiri 获取没有任何文本内容的完整 HTML

使用nokogiri剥离样式属性

如何使用 Nokogiri 在 TMX 中搜索道具元素

如何使用 Nokogiri 插入具有适当缩进的 HTML 块?