我应该如何解析Perl中的大型XML文件?

时间:2009-12-03 09:28:14

标签: xml perl sax

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

my $xml = new XML::Simple;

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

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

3 个答案:

答案 0 :(得分:14)

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

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

答案 1 :(得分:4)

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

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

我害怕的课程都是马匹

答案 2 :(得分:4)

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

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

另一方面,如果你需要将文件的一部分与另一部分交叉引用,那么DOM解析器或通过XPath访问将更有意义 - 以SAX解析器的“由内向外”方式编写它要求将是笨拙和棘手的。

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

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