在 Ruby 中,是否有可能让 DOM 解析一个庞大的 XML 的一部分,否则这些部分会被 SAX 解析?



我需要在Ruby中解析一个巨大的XML文件(70GB大(,目前我正在使用Nokogiri的SAX解析器。这个文件非常大,但它由一个根元素和许多条目组成,所有这些条目的大小都可以完美管理。必须以基于事件的方式进行所有解析是非常困难的。有没有办法将每个条目解析为 DOM,即使整个文件被解析为 SAX?

例如,我正在考虑使用所有start_elementclose_element调用构建 dom,在最后一个调用中,当记录关闭时,使用该 DOM 并在那里进行处理。毫无疑问,我不是第一个想到这种解决方案的人。

> rminner 在这里写道

"就我个人而言,我认为XML::D OM不会是正确的解决方案,如果你的输入xml文件非常大。我解析 xml 的常用选择是 XML::Twig。我正在使用它来解析非常大的文件,并且它以低内存使用率快速完成。这同样适用于其他模块,但我最熟悉的是XML::Twig。

"我举了一个简短的例子,关于如何使用XML::Twig进行解析。由于我不知道你到底打算做什么,所以我添加了一些示例方法调用来让你走上正确的轨道(以防你决定使用它(。

use strict;
use warnings;
use Data::Dumper;
#use Data::Dumper::Concise; # i prefer Data::Dumper::Concise
use XML::Twig;
# individually process each <signal> element
sub signal_handler {
my ($data, $twig, $elem) = @_;
# get the attributes of $elem (<signal>)
my $atts = $elem->atts();  
if ($atts->{'sigid'} == 3464) {
print "Found <signal> with sigid == 3464:n",$elem->sp
+rint(),"n";
print "<PRESS ENTER TO CONTINUE>";<STDIN>;
}
# if you want to access the element in a way similar to XML::S
+imple:
my $xml_simple_style_elem = $elem->simplify();
# check out the simplified structure:
print Dumper($xml_simple_style_elem);
print "<PRESS ENTER TO CONTINUE>";<STDIN>;
# Example for Data Collection:
my ($sigid, $id) = @{$atts}{qw/sigid id/};
if (defined $sigid and defined $id) {
$data->{sigid_id_count}{$sigid}{$id}++;
}
# get all elements below <signal> which are called <foo>
my @foo_subelements  = $elem->descendants('foo');
$twig->purge; # explicitly free the memory
};
sub main {
my $fn = shift @ARGV;
my %collected_data;
my $twig = XML::Twig->new(
twig_roots => {
'signal'     =>  sub {signal_handler(%collect
+ed_data, @_);},
},
);
eval {
$twig->parsefile($fn);
};
if ($@) {
print STDERR "Failed to parse '$fn' ($@)n";
}
if (%collected_data) {
print "I collected the following data:n",Dumper(%col
+lected_data);
}
}
main();

请点击这里查看完整文档

相关内容

最新更新