1

我想将以下有关历史发明的数据收集到一个方便的 Ruby 数据结构中:

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

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

似乎应该有几行代码的快速解决方案。使用 Rails 会有 Hash.from_xml 虽然我不确定它会正确处理属性。无论如何,我需要它作为一个独立的 Ruby 脚本。 根据有人发布的类似问题的代码,对于这个简单的任务, Nokogiri似乎过于复杂:http: //gist.github.com/335286。我找到了一个使用 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"

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

4

2 回答 2

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
于 2010-09-30T19:54:34.330 回答
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"
}
于 2010-09-30T20:20:54.060 回答