1

我用 Perl 编写了一个相当基本的 webapp,它使用XML::Twig. 这些 XML 文件相当大且复杂,因此我特意使用逐块变体,XML::Twig而不是“一次全部加载”方法。

但是,如果我加载大型 XML 文档,即使使用分块方法,这个 webapp 也会完全崩溃并死掉。我不知道为什么会发生这种情况,因为 web 应用程序托管在与 1and1.co.uk 共享的服务器上,我看不到 Apache 错误日志文件。即使将调用包装在一个eval{}块中,我也无法从死亡中捕捉到它。令人讨厌的是,它在我家里的开发服务器上运行良好,所以我无法重现这个问题。

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

我对此有点困惑,tbh,我试图通过谷歌的奇迹来找出是否parsefile()确实更有效parse(),但没有找到任何东西。有没有人碰巧知道?

4

2 回答 2

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;
}
于 2012-03-11T01:09:09.780 回答
-1

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

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

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

于 2012-03-10T21:26:34.207 回答