【问题标题】:How should I parse large XML files in Perl?我应该如何在 Perl 中解析大型 XML 文件?
【发布时间】:2009-12-03 09:28:14
【问题描述】:

像下面的代码那样读取 XML 数据是否会在内存中创建 DOM 树?

my $xml = new XML::Simple;

my $data = $xml->XMLin($blast_output,ForceArray => 1);

对于大型 XML 文件,我应该使用 SAX 解析器、处理程序等吗?

【问题讨论】:

  • 你想对文件做什么?您需要为将来的操作保留多少内存?在不知道您具体需要做什么的情况下,我们无法告诉您使用什么。
  • 通过数据点,我尝试使用 XML::Simple 来解析 Wikimedia Commons XML 转储,但这太大了(在运行 Ubuntu 的旧台式机上)。

标签: xml perl sax


【解决方案1】:

对于大型 XML 文件,您可以使用 XML::LibXML,如果文档适合内存,则在 DOM 模式下,或者使用拉模式(参见XML::LibXML::Reader)或XML::Twig(我写的,所以我' m 有偏差,但它通常适用于太大而无法放入内存的文件)。

我不是 SAX 的粉丝,它很难使用,实际上速度很慢。

【讨论】:

  • 我使用XML::Twig 处理大文件
  • XML::TwigXML::LibXML::Reader 我都喜欢,但我倾向于使用后者,因为它比 Twig 快得多...
【解决方案2】:

我对两者都同意。 XML::Simple 库将在内存中创建整个树,它是文件大小的一个很大的倍数。对于许多应用程序,如果您的 XML 超过 100MB 左右,那么在 perl 中完全加载到内存中几乎是不可能的。 SAX 解析器是一种在读取文件和打开或关闭标签时获取“事件”或通知的方法。

根据您的使用模式,基于 SAX 或 DOM 的解析器可能会更快:例如,如果您尝试处理大文件中的几个节点或每个节点,则 SAX 模式可能是最好的.例如,阅读大型 RSS 提要并尝试解析其中的每个项目。

另一方面,如果您需要交叉引用文件的一部分与另一部分,则使用 DOM 解析器或通过 XPath 访问会更有意义 - 以 SAX 解析器的“由内而外”方式编写它requires 会很笨拙和棘手。

我建议至少尝试一次 SAX 解析器,因为这样做所需的事件驱动思维是很好的练习。

我在使用 XML::SAX::Machines 在 perl 中设置 SAX 解析方面取得了巨大成功——如果您想要多个过滤器和管道,那么设置起来很容易。对于更简单的设置(即 99% 的时间),您只需要一个 sax 过滤器(查看 XML::Filter::Base)并告诉 XML::SAX::Machines 只使用解析文件(或从文件句柄读取)你的过滤器。 Here's a thorough article.

【讨论】:

    【解决方案3】:

    我以前没有使用过 XML::Simple 模块,但从documentation 看来,它似乎在内存中创建了一个简单的哈希。这不是一个完整的 DOM 树,但可能足以满足您的要求。

    对于大型 XML 文件,使用 SAX 解析器会更快,并且内存占用更少,但是这又取决于您的需要。如果您只需要以串行方式处理数据,那么使用XML::SAX 可能会满足您的需求。如果您需要操作整棵树,那么使用 XML::LibXML 之类的东西可能会更好。

    恐怕课程全是马

    【讨论】:

      猜你喜欢
      • 2010-12-10
      • 1970-01-01
      • 2012-02-11
      • 2014-07-11
      • 1970-01-01
      • 1970-01-01
      • 2013-07-17
      • 2011-05-09
      • 2012-03-27
      相关资源
      最近更新 更多