[英]How can I create the XML::Simple data structure using a Perl XML SAX parser?
简介 :我正在寻找一个快速的XML解析器(很可能是一些标准SAX解析器的包装器),它将生成与XML :: Simple生成的每个记录数据结构100%相同的每个记录数据结构。
细节 :
我们有一个庞大的代码基础结构,它依赖于处理记录,并且希望记录是XML :: Simple生成的格式的数据结构,因为它从早期的侏罗纪时代就一直使用XML :: Simple。
一个简单的XML示例是:
<root>
<rec><f1>v1</f1><f2>v2</f2></rec>
<rec><f1>v1b</f1><f2>v2b</f2></rec>
<rec><f1>v1c</f1><f2>v2c</f2></rec>
</root>
例如粗略的代码是:
sub process_record { my ($obj, $record_hash) = @_; # do_stuff }
my $records = XML::Simple->XMLin(@args)->{root};
foreach my $record (@$records) { $obj->process_record($record) };
众所周知,XML :: Simple很简单。 更重要的是,由于是一个DOM解析器并且需要在内存中构建/存储100%的数据,因此它非常慢且内存耗尽。 因此,它不是解析包含大量小记录的XML文件的最佳工具。
但是,重写整个代码(包含大量“process_record”类似方法)来使用标准SAX解析器似乎是一项不值得资源的大任务,即使以使用XML :: Simple为代价也是如此。
我正在寻找一个现有的模块,它可能基于一个SAX解析器(或任何快速,内存占用很少),可以用来根据上面的图片逐个生成$record
hashrefs,可以传递给$obj->process_record($record)
并且与XML :: Simple的hashrefs完全相同。
我不在乎新模块的界面是什么; 例如,我是否需要调用next_record()
或给它一个接受记录的回调coderef。
XML::Twig
有一个简化方法,你可以调用XML元素,根据文档说:
返回一个与XML :: Simple相似的数据结构
这是一个例子:
use XML::Twig;
use Data::Dumper;
my $twig = XML::Twig->new(
twig_handlers => {
rec => \&rec,
}
)->parsefile( 'data.xml' );
sub rec {
my ($twig, $rec) = @_;
my $data = $rec->simplify;
say Dumper $data;
$rec->purge;
}
NB。 $ rec-> purge立即从内存中清除记录。
针对XML示例运行此操作会产生以下结果:
$VAR1 = {
'f1' => 'v1',
'f2' => 'v2'
};
$VAR1 = {
'f1' => 'v1b',
'f2' => 'v2b'
};
$VAR1 = {
'f1' => 'v1c',
'f2' => 'v2c'
};
我希望可疑的是XML :: Simple :)
/ I3az /
作为XML :: Simple的作者,我想纠正你的问题中的一些误解。
XML :: Simple不是DOM解析器,实际上它根本不是解析器。 它将所有解析任务委托给SAX解析器或XML :: Parser。 解析的速度取决于系统上默认的解析器模块。 当您为XML :: Simple分发运行'make test'时,输出将列出默认解析器。
如果你的系统上的默认解析器是XML :: SAX :: PurePerl,那么它将是缓慢的,更重要的是也是错误的。 如果是这种情况,那么我建议安装XML :: Expat或XML :: ExpatXS以立即加速。 (最后安装的SAX解析器将是该点的默认值)。
话虽如此,你的要求有点矛盾,你想要的东西可以将整个文档作为哈希返回,但你不希望解析器将整个文档放入内存中。
我了解您的短期目标,但作为一个长期解决方案,我建议您将代码迁移到XML :: LibXML。 它是一个DOM解析器,但速度非常快,因为所有繁琐的工作都是用C语言完成的。最重要的是内置的XPath支持使得它比XML :: Simple更简单易用 - 请参阅本文 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.