如何使用Nokogiri访问属性

Liz*_*Liz 56 ruby builder nokogiri

我有一个访问某些属性值的简单任务.下面是一个简单的脚本,用于Nokogiri::XML::Builder创建一个简单的xml doc.

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"]
Run Code Online (Sandbox Code Playgroud)

结果如下:

<?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
Run Code Online (Sandbox Code Playgroud)

生成的XML看起来很好.但是,我尝试访问属性会导致生成错误

Document already has a root node
Run Code Online (Sandbox Code Playgroud)

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

ato*_*les 66

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

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

请注意,如果您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 
Run Code Online (Sandbox Code Playgroud)

  • 伟大的东西,这在整个周末的代码节日期间凌晨2:22帮助了我.格拉西亚斯. (4认同)

ben*_*ape 48

下面是一种稍微简洁的方法来访问属性Nokogiri(假设你已经将xml存储在一个被调用的变量中xml,如@atomicules的回答所述):

xml.xpath("//Placement").attr("messageId")
Run Code Online (Sandbox Code Playgroud)