对于2.4MB的XML文件,您建议使用哪个Ruby XML库?

对于2.4MB的XML文件,您建议使用哪个Ruby XML库?,xml,ruby,Xml,Ruby,我有一个2.4 MB的XML文件,是从Microsoft Project导出的(嘿,我是这里的受害者!),我被要求从中提取某些详细信息,以便重新演示。忽略请求的智能性或其他方面,从Ruby的角度来看,我应该首先尝试哪个库 我知道以下情况(无特定顺序): 我更喜欢包装成Ruby gem的东西,我怀疑Chilkat库不是这样的 性能不是一个主要问题-我不认为这件事需要每天运行一次以上(更可能是一周一次)。我更感兴趣的是一些与XML相关的东西一样易于使用 编辑:我试过双子座的: 从一个国家

我有一个2.4 MB的XML文件,是从Microsoft Project导出的(嘿,我是这里的受害者!),我被要求从中提取某些详细信息,以便重新演示。忽略请求的智能性或其他方面,从Ruby的角度来看,我应该首先尝试哪个库

我知道以下情况(无特定顺序):

我更喜欢包装成Ruby gem的东西,我怀疑Chilkat库不是这样的

性能不是一个主要问题-我不认为这件事需要每天运行一次以上(更可能是一周一次)。我更感兴趣的是一些与XML相关的东西一样易于使用

编辑:我试过双子座的:

从一个国家的角度来看,hpricot是最容易的。例如,提取此XML中SaveVersion标记的内容(保存在名为“test.XML”的文件中)

hpricot似乎相对不关心名称空间,在本例中这很好:只有一个名称空间,但复杂文档可能会出现问题。由于hpricot的速度也很慢,我宁愿想象这将是一个自行解决的问题

libxmlruby的速度快了一个数量级,能够理解名称空间(我花了好几个小时才弄明白这一点),并且与xmlmetal-XPath查询和所有其他内容都非常接近。如果像我一样,只在极端胁迫的情况下打开XML文档,那么这不一定是一件好事。helper模块在提供如何有效处理默认名称空间的示例方面非常有用。这大概就是我最终得到的结果(我并没有以任何方式断言它的美丽、正确或其他价值,这正是我现在所处的位置):

我仍然在争论其利弊:libxml的极端严格性,hpricot的代码风格

稍后再编辑:我发现了HappyMapper(“gem安装HappyMapper”),这是一个非常有前途的工具,尽管它还处于早期阶段。它是声明性的,大部分是有效的,尽管我已经发现了一些我还没有修复的边缘案例。它可以让你做这样的事情,解析我的谷歌阅读器OPML:

module OPML
  class Outline
    include HappyMapper
    tag 'outline'
    attribute :title, String
    attribute :text, String
    attribute :type, String
    attribute :xmlUrl, String
    attribute :htmlUrl, String
    has_many :outlines, Outline
  end
end

xml_string = File.read("google-reader-subscriptions.xml")

sections = OPML::Outline.parse(xml_string)
我已经很喜欢它了,尽管它还不完美。

可能是最适合您的工具——它易于使用,应该可以毫无问题地处理2mg文件

Speedwise libxml应该是最好的。几个月前,我为python使用了libxml2绑定(当时rb-libxml已经过时)。流媒体接口最适合我
(RubyGem中的LibXML::XML::Reader)。它允许在文件下载时处理文件,比SAX更友好一些,并且允许我在一分钟多一点的时间内将数据从互联网上的30mb xml文件加载到MySQL数据库。

Nokogiri使用一个干净的Rubyish API包装libxml2和libxslt,该API支持名称空间、XPath和CSS3查询。也很快。

哦,不!一个2.4 mb的XML文件!恐怖!嗯,我想如果是2.4GB,答案可能会有所不同……;)这些天我推荐的是Hpricot。根据我的经验,它稳定得多,功能齐全,维护良好。是的,我同意,Nokogiri是目前的发展方向。但是,由于基础依赖性,它只支持XPATH 1.0
doc = Hpricot.XML(open('test.xml'))
version = (doc/:Project/:SaveVersion).first.inner_html
xml_parser = XML::Parser.new
xml_parser.string = File.read(path)
doc = xml_parser.parse
@root = doc.root
@scopes = { :in_node => '', :in_root => '/', :in_doc => '//' }
@ns_prefix = 'p'
@ns = "#{@ns_prefix}:#{@root.namespace[0].href}"
version = @root.find_first(xpath_qry("Project/SaveVersion", :in_root), @ns).content.to_i

def xpath_qry(tags, scope = :in_node)
  "#{@scopes[scope]}" + tags.split(/\//).collect{ |tag| "#{@ns_prefix}:#{tag}"}.join('/')
end
module OPML
  class Outline
    include HappyMapper
    tag 'outline'
    attribute :title, String
    attribute :text, String
    attribute :type, String
    attribute :xmlUrl, String
    attribute :htmlUrl, String
    has_many :outlines, Outline
  end
end

xml_string = File.read("google-reader-subscriptions.xml")

sections = OPML::Outline.parse(xml_string)