在perl中串行处理XML数据

在perl中串行处理XML数据,xml,linux,perl,centos,Xml,Linux,Perl,Centos,我想知道在我的情况下,对于Perl,哪种XML解析器最适合我。我读了很多书,并尝试了XML::LibXML和XML::SAX。第一个使用了太多的内存,第二个对我来说似乎没有那么快(即使在关闭纯perl解析器之后) 我的需求相当具体。我通过Net::SSH库收到了高达50MB的巨大响应。我希望在接收数据时将其传递给XML库,以便在内存中保留最少的数据量。然后我需要在某些标记中查找数据,并对其执行任何操作,在某些情况下求和一组值,在其他情况下,只提取值并将其写入文件或其他任何内容。因此,我需要一个X

我想知道在我的情况下,对于Perl,哪种XML解析器最适合我。我读了很多书,并尝试了
XML::LibXML
XML::SAX
。第一个使用了太多的内存,第二个对我来说似乎没有那么快(即使在关闭纯perl解析器之后)

我的需求相当具体。我通过
Net::SSH
库收到了高达50MB的巨大响应。我希望在接收数据时将其传递给XML库,以便在内存中保留最少的数据量。然后我需要在某些标记中查找数据,并对其执行任何操作,在某些情况下求和一组值,在其他情况下,只提取值并将其写入文件或其他任何内容。因此,我需要一个XML解析器,它可以连续工作,工作迅速,并且使用最少的内存。我得到的数据是1024字节的数据块,因此我希望能够像
$myparser->sendData($mynewData)
这样做,然后在打开或关闭新标记时调用函数,就像
XML::SAX
那样

我不一定需要XPath或XSLT。

我建议使用

该模块使用方便,可以连续读取数据,无需占用大量内存

XML::Twig
最显著的特点之一可能是,它允许在所谓的混合模型中解析XML:您可以解析整个文档(需要整个文档和大量内存),您可以使用回调解析小数据块(允许流式传输、小内存消耗),或者您可以使用它们的任意组合


这种组合模式是最方便的功能—从流中加载小叶子,您可以免费有效地访问它的所有小分支。

您也可以使用plain old,它几乎满足了您的要求:

“此模块提供解析XML文档的方法。它构建在XML::Parser::Expat之上,这是James Clark的Expat库的低级接口。对其中一个解析方法的每次调用都会创建一个新的XML::Parser::Expat实例,然后用于解析文档。创建XML::Parser对象时,可能会提供Expat选项。然后,在每次解析调用时,这些选项都会传递给Expat对象。它们还可以作为解析方法的额外参数提供,在这种情况下,它们会覆盖在XML::Parser创建时提供的选项。”

Expat是一个基于事件的解析器。当解析器识别文档的某些部分(例如XML元素的开始或结束标记)时,将使用合适的参数调用为该类型事件注册的任何处理程序。”


我使用它进行解析,即使在压缩后,解析的大小也有几GB,并且发现它在这方面工作得非常好。相比之下,一个50 MB的文件应该是小菜一碟。

XML::LibXML还附带了两个流解析器,它们应该比纯Perl解决方案更快:

XML::LibXML::SAX 与XML::SAX兼容的SAX解析器

XML::LibXML::Reader
libxml2的pull解析器的接口。它提供了一个比SAX更简单的接口,而且速度更快。据我所知,XML::LibXML::Reader是解析XML文件而不将其完全加载到内存中的最快的Perl模块。

感谢mvp和@Ilmarikaron,我将尝试这些,并在确定哪一个最有效时标记绿色标记。这可能需要一段时间:-)我现在已经测试了几个xml解析器(以及只使用一个正则表达式),对于50MB的文件,我得到的结果是正则表达式不到1秒,xml::Parser 21秒,xml::SAX 22秒,twig 70秒。在所有情况下,我只是查找名为“interface”的节点”他数了数。内存使用对于他们来说都是最小的。有趣的是,所有的解析器都比正则表达式慢得多。我倾向于使用XML::Parser,因为它已经安装在服务器上,使用简单,速度快。但也许我对twig做了一些错误的事情?如果你只是在计算节点,你应该使用
XML::twig
ignore
方法或类似的方法,比如
setIgnoreEltsHandler
——它会大大加快速度,因为不需要构建twig。另外,您应该在回调中调用
purge
方法来释放分配给twig的内存-这将使它更快地运行Hanks Ilmari。你多快找到的?我发现perl可以加载一个50MB的文件并在不到1秒的时间内搜索整个文件,而XML解析器似乎都需要20秒。听起来正确吗?我刚刚试过运行,它在2 GHz Intel Xeon服务器上的1.7 GB最新芬兰维基百科转储上每秒运行约10 MB。XML解析器比纯正则表达式慢,因为它们考虑了编写XML的各种方式,这需要一些时间。但是,除非您完全控制XML的编写方式,否则额外的时间将是快速编写和正确编写之间的区别(简单的正则表达式可能会对标记中属性的顺序和可忽略空格的使用等敏感,并且可能会在错误的位置(例如注释中)匹配内容)@ebohlman我肯定对使用regex不感兴趣,我认为这是有史以来最大的黑客攻击,但这里的工作人员就是。我正试图找到一个性能相当的解决方案,这样我们就可以编写出不会因XML中的细微差异而崩溃的代码。我至少可以看到正则表达式失败的10种方式。这20秒并不是一个真正的问题,因为返回响应需要3分钟的时间,我们可以一边处理响应。嗨,Nick,你知道你是否可以将数据分块传递给XML::LibXML::SAX吗?我只能看到串行解析文件的方法,但我正在从PerlSSH库接收数据。类似于XML::Parser的parse_more函数。