Ruby中的XML到哈希表:解析历史发明列表

时间:2010-09-30 19:10:17

标签: ruby xml nokogiri hpricot

我想将以下有关历史发明的数据投入到方便的Ruby数据结构中:

http://yootles.com/outbox/inventions.xml

请注意,所有数据都在XML属性中。

似乎应该有几行代码的快速解决方案。 使用Rails会有Hash.from_xml虽然我不确定是否能正确处理属性。 无论如何,我需要将它作为一个独立的Ruby脚本。 Nokogiri对于基于此代码的简单任务而言似乎过于复杂,有人发布了类似问题:http://gist.github.com/335286。 我发现了simple solution using hpricot,但它似乎没有处理XML属性。 也许这是一个简单的扩展? 最后有ROXML,但看起来比nokogiri更重要。

为了使问题具体化(并且有明显的别有用心),让我们说答案应该是一个完整的Ruby脚本,它从上面的URL中汲取XML并像这样吐出CSV:

id, invention, year, inventor, country
RslCn, "aerosol can", 1926, "Erik Rotheim", "Norway"
RCndtnng, "air conditioning", 1902, "Willis Haviland Carrier", "US"
RbgTmtv, "airbag, automotive", 1952, "John Hetrick", "US"
RplnNgnpwrd, "airplane, engine-powered", 1903, "Wilbur and Orville Wright", "US"

我会自己回答并发布它,除非有人用明显优越的东西击败我。谢谢!

2 个答案:

答案 0 :(得分:1)

使用REXML和open-uri:

require "rexml/document"
require "open-uri"

doc = REXML::Document.new open( "http://yootles.com/outbox/inventions.xml" ).read

puts [ 'id', 'invention', 'year', 'inventor', 'country' ].join ','
doc.root.elements.each do |invention|
  inventor = invention.elements.first
  data = []
  data << invention.attributes['id']
  data << '"' + invention.attributes['name'] + '"'
  data << invention.attributes['year']
  data << '"' + inventor.attributes['name'] + '"'
  data << '"' + inventor.attributes['country'] + '"'
  puts data.join ','
end

答案 1 :(得分:1)

事实证明,这比我对Nokogiri的想法更简单:

require 'rubygems'
require 'nokogiri' # needs sudo port install libxslt and stuff; see nokogiri.org
require 'open-uri'

@url = 'http://yootles.com/outbox/inventions.xml'

doc = Nokogiri::XML(open(@url))
puts("id, invention, year, inventor, country")
doc.xpath("//invention").each{ |i| 
  inventor = i.xpath("inventor").first
  print i['id'], ", \"", i['name'], "\", ", i['year'], ", \"", 
  inventor['name'], "\", \"", inventor['country'], "\"\n"
}