我对使用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/提高到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种方法,你可以使用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 Select 器,可以使用几乎相同的代码:

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

Ruby相关问答推荐

如何使用另一个Ruby 中的Ruby 中的区域设置?

Ruby:一个方法可以返回不同类型的对象吗?

用函数组合枚举器的Ruby方法

如何用 yield_self 断链

将数组转换为哈希,其中键是索引

Symfony 2assets资源过滤器异常中的指南针

ActiveRecord::AdapterNotSpecified 数据库配置未指定适配器

Ruby $:.unshift File.dirname(__FILE__)

如何以不同 colored颜色 输出我的 ruby​​ 命令行文本

使用正则表达式在第一个逗号之前提取文本

无法在 OSX Lion 上使用 RVM 安装 Ruby 企业版

用mustache迭代数组

如何判断是否安装了gem?

从命令行使用Bundle 器将 gem 添加到 gemfile

处理来自 Net::HTTP 的异常的最佳方法是什么?

map、each 和 collect 有什么区别?

`File` 对象访问模式的区别(即 w+, r+)

Ruby 哈希白名单过滤器

Ruby:从 Ruby 中的变量创建哈希键和值

带有类名的动态类定义