代码之家  ›  专栏  ›  技术社区  ›  dreeves

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

  •  1
  • dreeves  · 技术社区  · 14 年前

    我想把以下有关历史发明的数据整合成一个方便的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 回复  |  直到 9 年前
        1
  •  1
  •   drummondj    14 年前

    使用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
    
        2
  •  1
  •   dreeves    14 年前

    结果证明这比我想象中的诺科吉里简单:

    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"
    }