我正在使用XML::Twig解析大型XML文件(60GB +)并在OO(Moose)脚本中使用它。我使用twig_handlers
选项在它们被读入内存后立即解析元素。但是,我不确定如何处理Element和Twig。
在我使用Moose(和OO)之前,我的脚本看起来如下(和工作):
my $twig = XML::Twig->new(
twig_handlers => {
$outer_tag => \&_process_tree,
}
);
$twig->parsefile($input_file);
sub _process_tree {
my ($fulltwig, $twig) = @_;
$twig->cut;
$fulltwig->purge;
# Do stuff with twig
}
现在我就这样做了。
my $twig = XML::Twig->new(
twig_handlers => {
$self->outer_tag => sub {
$self->_process_tree($_);
}
}
);
$twig->parsefile($self->input_file);
sub _process_tree {
my ($self, $twig) = @_;
$twig->cut;
# Do stuff with twig
# But now the 'full twig' is not purged
}
问题是我现在看到我错过了fulltwig
的清除。我认为 - 在第一个,非OO版本 - 清除将有助于节省内存:尽快摆脱fulltwig。但是,当使用OO(并且必须依赖处理程序中的显式sub{}
)时,我不知道如何清除整个树枝,因为文档说明了
$ _也设置为元素,因此很容易编写内联处理程序 像
para => sub { $_->set_tag( 'p'); }
所以他们谈论你想要处理的元素,而不是fulltwig本身。那么如果它没有传递给子程序,怎么能删除呢?
答案 0 :(得分:6)
处理程序仍然得到完整的树枝,你只是没有使用它(使用$ _代替)。
事实证明,您仍然可以在树枝上调用purge
(我通常称之为“元素”,或文档中的elt
):$_->purge
将按预期工作,清除完整的树枝直到$ _;
清洁工(恕我直言)的方式是实际获取所有参数并清除完整的枝条:
my $twig = XML::Twig->new(
twig_handlers => {
$self->outer_tag => sub {
$self->_process_tree(@_); # pass _all_ of the arguments
}
}
);
$twig->parsefile($self->input_file);
sub _process_tree {
my ($self, $full_twig, $twig) = @_; # now you see them!
$twig->cut;
# Do stuff with twig
$full_twig->purge; # now you don't
}