使用Ruby解析XML

n8g*_*ard 41 ruby xml-parsing

我是使用XML的新手,但只是需要放弃我的膝盖.我得到了一个通常的(对我来说)XML格式.标签内有冒号.

<THING1:things type="Container">
  <PART1:Id type="Property">1234</PART1:Id>
  <PART1:Name type="Property">The Name</PART1:Name>
</THING1:things>
Run Code Online (Sandbox Code Playgroud)

它是一个大文件,除此之外还有更多内容,但我希望这种格式对某人来说很熟悉.有没有人知道如何处理这种XML文档?

我宁愿不只是写一个解析文本的蛮力方式,但我似乎无法用REXML或Hpricot取得任何进展,我怀疑这是由于这些不寻常的标签.

我的红宝石代码:

    require 'hpricot'
    xml = File.open( "myfile.xml" )

    doc = Hpricot::XML( xml )

   (doc/:things).each do |thg|
     [ 'Id', 'Name' ].each do |el|
       puts "#{el}: #{thg.at(el).innerHTML}"
     end
   end
Run Code Online (Sandbox Code Playgroud)

...刚从...取消:http://railstips.org/blog/archives/2006/12/09/parsing-xml-with-hpricot/

我想我可以从这里找到一些东西,但这段代码什么都没有.它没有错误.它只是回来了.

jmd*_*din 74

正如@pguardiario所提到的,Nokogiri是事实上的XML和HTML解析库.如果您想在示例中打印出IdName值,请按以下步骤操作:

require 'nokogiri'

xml_str = <<EOF
<THING1:things type="Container">
  <PART1:Id type="Property">1234</PART1:Id>
  <PART1:Name type="Property">The Name</PART1:Name>
</THING1:things>
EOF

doc = Nokogiri::XML(xml_str)

thing = doc.at_xpath('//things')
puts "ID   = " + thing.at_xpath('//Id').content
puts "Name = " + thing.at_xpath('//Name').content
Run Code Online (Sandbox Code Playgroud)

几点说明:

  • at_xpath是为了匹配一件事.如果您知道自己有多个项目,则需要使用xpath.
  • 根据您的文档,名称空间可能会有问题,因此调用doc.remove_namespaces!可以提供帮助(请参阅此答案以进行简短讨论).
  • 您可以使用这些css方法,而不是xpath如果您对这些方法感觉更舒服.
  • 绝对可以使用它irbpry调查方法.

资源

更新

要处理多个项目,您需要一个根元素,并且需要//xpath查询中删除它.

require 'nokogiri'

xml_str = <<EOF
<root>
  <THING1:things type="Container">
    <PART1:Id type="Property">1234</PART1:Id>
    <PART1:Name type="Property">The Name1</PART1:Name>
  </THING1:things>
  <THING2:things type="Container">
    <PART2:Id type="Property">2234</PART2:Id>
    <PART2:Name type="Property">The Name2</PART2:Name>
  </THING2:things>
</root>
EOF

doc = Nokogiri::XML(xml_str)
doc.xpath('//things').each do |thing|
  puts "ID   = " + thing.at_xpath('Id').content
  puts "Name = " + thing.at_xpath('Name').content
end
Run Code Online (Sandbox Code Playgroud)

这会给你:

Id   = 1234
Name = The Name1

ID   = 2234
Name = The Name2
Run Code Online (Sandbox Code Playgroud)

如果您对CSS选择器更熟悉,可以使用这几乎相同的代码:

doc.css('things').each do |thing|
  puts "ID   = " + thing.at_css('Id').content
  puts "Name = " + thing.at_css('Name').content
end
Run Code Online (Sandbox Code Playgroud)


Ili*_*asT 31

如果在Rails环境中,Hash对象被扩展,并且可以利用该方法from_xml:

xml = File.open("myfile.xml")
data = Hash.from_xml(xml)
Run Code Online (Sandbox Code Playgroud)

  • `from_xml`不是本机Hash方法,它是Rails/ActiveSupport的一部分.如果你在那个环境中,它可以正常工作. (13认同)
  • @YakobUbaidi请注意该帖子的前五个字。 (2认同)