XML :: Twig:parsefile()比parse()更有效吗?

时间:2012-03-10 20:44:23

标签: xml perl xml-twig

我在Perl中编写了一个相当基本的Web应用程序,它使用XML::Twig处理XML文件。这些XML文件相当庞大且复杂,所以我故意使用chunk varient XML::Twig而不是“一次加载所有”方法。

但是,如果我加载大型XML文档,即使使用分块方法,这个webapp也会完全崩溃并死掉。我无法得到关于为什么会发生这种情况的任何线索,因为webapp托管在1and1.co.uk的共享服务器上,我无法看到Apache错误日志文件。即使将呼叫包裹在eval{}块中,我也无法从死亡中捕获它。令人讨厌的是,它在我家的开发服务器上工作正常,所以我无法重现这个问题。

为了使它工作,我做了一个更改,以便不是使用parse()方法并传入包含整个XML的标量,而是将XML写入文件,然后使用parsefile( $filename )代替。当我做出改变时,它起作用了。

我对此感到有些困惑,tbh,我试图通过谷歌的奇迹找出parsefile()确实比parse()效率更高,但找不到任何东西。有人碰巧知道吗?

2 个答案:

答案 0 :(得分:2)

看看来源。他们是一回事。

XML::Twig parsefile只是一个扩展的XML::Parser::parsefile(超类):

sub parsefile
  { my $t= shift;
    if( -f $_[0] && ! -s $_[0]) { return _checked_parse_result( undef, "empty file '$_[0]'"); }
    $t= eval { $t->SUPER::parsefile( @_); };
    return _checked_parse_result( $t, $@);
  }

XML::Parser中,parsefile只是parse的封套:

sub parsefile {
  my $self = shift;
  my $file = shift;
  local(*FILE);
  open(FILE, $file) or  croak "Couldn't open $file:\n$!";
  binmode(FILE);
  my @ret;
  my $ret;

  $self->{Base} = $file;

  if (wantarray) {
    eval {
      @ret = $self->parse(*FILE, @_);
    };
  }
  else {
    eval {
      $ret = $self->parse(*FILE, @_);
    };
  }
  my $err = $@;
  close(FILE);
  die $err if $err;

  return unless defined wantarray;
  return wantarray ? @ret : $ret;
}

答案 1 :(得分:-1)

我确信1和1允许您访问Apache日志文件,因为它是调试CGI和Web应用程序(如您的)的重要工具。给他们一个喊叫,并问他们该怎么做。

如果您的XML文件很大,那么它会破坏在块模式下使用XML::Twig的重要性。您的应用程序似乎也可能在服务器上失败,因为它已超出其内存配额。再一次,打电话给您的网络托管公司会告诉您是否是这种情况。

您的XML如何首先进入内存?如果您正在从XML文件中将其粘贴到内存中,那么只需保留原样,然后让XML::Twig直接从文件中读取。如果要从远程URL获取XML,请记住XML::Twig具有parseurl方法,这将避免将数据提取到本地文件。我想不出另一个可能的来源,所以你必须解释。