【问题标题】:Which Ruby XML library would you recommend for a 2.4MB XML file? [closed]对于 2.4MB 的 XML 文件,您会推荐哪个 Ruby XML 库? [关闭]
【发布时间】:2008-09-24 10:10:25
【问题描述】:

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

我知道以下内容(排名不分先后):

我更喜欢打包成 Ruby gem 的东西,我怀疑 Chilkat 库不是。

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

编辑:我尝试了宝石化的:

hpricot 是最简单的。例如,要提取此 XML 中 SaveVersion 标记的内容(保存在名为“test.xml”的文件中)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Project xmlns="http://schemas.microsoft.com/project">
    <SaveVersion>12</SaveVersion>
</Project>

采取这样的方式:

doc = Hpricot.XML(open('test.xml'))
version = (doc/:Project/:SaveVersion).first.inner_html

hpricot 似乎相对不关心命名空间,在这个例子中这很好:只有一个,但可能是复杂文档的问题。由于 hpricot 也很慢,我宁愿认为这将是一个自行解决的问题。

libxml-ruby 速度快了一个数量级,可以理解命名空间(我花了好几个小时才弄清楚这一点),并且完全接近 XML 金属 - XPath 查询和所有其他东西都在那里。如果像我一样只在极端胁迫的情况下打开 XML 文档,这未必是件好事。帮助器模块主要有助于提供如何有效处理默认命名空间的示例。这大致就是我最终的结果(我并没有以任何方式断言它的美丽、正确性或其他价值,这就是我现在所处的位置):

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

我仍在争论利弊:libxml 更严谨,hpricot 为 _why 代码的纯粹风格。

稍后再编辑:我发现了HappyMapper('gem install 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)

我已经喜欢它了,尽管它还不完美。

【问题讨论】:

  • 哦,不!一个 2.4 mb 的 XML 文件!恐怖!
  • 好吧,如果是 2.4 GB,我想答案可能会有所不同... ;)

标签: xml ruby


【解决方案1】:

Nokogiri 使用干净的 Rubyish API 包装 libxml2 和 libxslt,支持命名空间、XPath 和 CSS3 查询。也快。 http://nokogiri.org/

【讨论】:

  • 注意,由于底层依赖,只支持XPATH 1.0
【解决方案2】:

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

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

【讨论】:

  • 这些天我推荐Nokogiri而不是Hpricot。根据我的经验,它更加稳定,功能非常齐全且维护良好。
  • 是的,我同意,Nokogiri 是这些天要走的路
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-15
  • 2010-12-13
  • 2010-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多