在子处理程序中清除XML Twig

Bra*_*roy 7 xml perl xml-twig

我正在使用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
}
Run Code Online (Sandbox Code Playgroud)

现在我就这样做了.

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
}
Run Code Online (Sandbox Code Playgroud)

问题是,我现在看到我错过了清除fulltwig.我认为 - 在第一个,非OO版本 - 清除将有助于节省内存:尽快摆脱fulltwig.但是,当使用OO(并且必须依赖于sub{}处理程序内部的显式)时,我看不出如何清除完整的树枝,因为文档说明了

$ _也设置为元素,因此很容易编写内联处理程序

para => sub { $_->set_tag( 'p'); }

所以他们谈论你想要处理的元素,而不是fulltwig本身.那么如果没有传递给子程序,怎么能删除呢?

mir*_*rod 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
}
Run Code Online (Sandbox Code Playgroud)

  • 清除时应该没有区别。最重要的是在开始解析下一个子树之前回收内存。谢谢;--) (2认同)