ruby - 使用 Ruby 解析 XML

标签 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>

这是一个大文件,其中包含的内容远不止于此,但我希望有人会熟悉这种格式。有谁知道处理此类 XML 文档的方法吗?

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

我的 ruby 代码:

    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

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

我想我可以从这里找出一些东西,但这段代码没有返回任何内容。它没有错误。它只是返回。

最佳答案

正如@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

一些注意事项:

  • at_xpath 是为了匹配一个东西。如果您知道自己有多个项目,则需要改用 xpath
  • 根据您的文档,命名空间可能会出现问题,因此调用 doc.remove_namespaces! 会有所帮助(有关简短讨论,请参阅 this answer)。
  • 您可以使用 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

这会给你:

Id   = 1234
Name = The Name1

ID   = 2234
Name = The Name2

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

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

关于ruby - 使用 Ruby 解析 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11198239/

相关文章:

MySQL 事件记录写入新创建的表时出现问题

ruby - 使用Ruby,您可以在Begin循环中使用多个救援吗?

ruby-on-rails - Rails API - 期望显示已创建对象的 json。获取没有对象的 302 状态码

java - 在 Java 或 Scala 中解析扁平的、大量属性的 xml 的最快方法

ruby - 使用 Ruby 将 XML 转换为 JSON 并将其保存为单独的文件

javascript - 以 Rails 4 形式将 <ul> 列表作为参数数组提交,使用 javascript 将 params 值添加到 params 哈希

ruby - 使用 RSpec 我如何测试救援异常 block 的结果

JavaScript - 解析 XML 数据

c++ - QTDom - 递归地将子元素添加到特定元素

c++ - 如何在没有任何其他修改的情况下在 C++ 中对 XML 字符串进行 "pretty print"处理?