2012-03-10 68 views
1

我已经用Perl编写了一个相当基本的Web应用程序,它使用XML::Twig来处理XML文件。这些XML文件相当大且复杂,所以我故意使用块大小为XML::Twig的块而不是“一次加载”方法。XML :: Twig:parsefile()比parse()更高效吗?

但是,如果我加载大型XML文档,即使使用分块方法,此webapp也会完全崩溃并死亡。我无法得到任何线索,为什么发生这种情况,因为webapp托管在1and1.co.uk的共享服务器上,而且我看不到Apache错误日志文件。即使将电话打包在eval{}区块中,我也无法从死亡中捕捉到它。令人烦恼的是,它在我家的开发服务器上工作正常,所以我不能再现问题。

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

我对此有点困惑,tbh,并且我试图通过Google的奇迹发现是否确实更有效,parse(),但未能找到任何东西。有人碰巧知道吗?

回答

-1

我相信1和1允许您访问Apache日志文件,因为它是调试CGI和Web应用程序(如您的)的重要工具。给他们留言,并问他们如何去做。

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

XML是如何进入内存的?如果您从XML文件中将内容篡改到内存中,请将修补程序保持原样并直接从文件中读取XML::Twig。如果您从远程URL获取XML,请记住XML::Twig有一个parseurl方法,该方法可避免将数据提取到本地文件。我想不出另一个可能的来源,所以你必须解释。

+0

的1and1不给访问错误日志文件。我没有看到如何解析块中的XML会破坏使用XML :: Twig的重点,因为这是使用它的关键。 1and1不会给我额外的记忆;地狱,这些人拒绝在他们的debian服务器上部署标准软件包(比如libxml-twig-perl!)。至于XML,它从URL下载并存储到磁盘;这需要发生,因为XML太大了,当服务器尝试将它保存在内存中时,服务器崩溃时会出现大量(+ 5MB)XML文件 - 我不认识你。 – Kenny 2012-03-11 09:56:49

+0

然后你有我的同情心:限制访问错误日志是奇怪的!我的意思是将整个XML文件保存在内存中会损害块处理的重要性,因为您已经使用了大量内存。我以为你将内存中的XML转储到一个文件中,并使用'XML :: Twig'来处理它。由于它来自远程URL,因此可以避免将其保存在本地,并使用'parseurl'而不是'parsefile'。 – Borodin 2012-03-11 14:11:17

2

看看源代码。他们是一样的东西。

XML::Twigparsefile只是一个扩展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, [email protected]); 
    } 

XML::Parserparsefile只是一个围绕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 = [email protected]; 
    close(FILE); 
    die $err if $err; 

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

我可能误解了你的答案,但那不是比较XML :: Twig的parsefile()和parse()?它比较XML :: Parser中的两个方法吗?假设其中一个确实只是另一个的包装......为什么一个人会崩溃而另一个人使用同一个大型XML文件?这让我感到困惑。 – Kenny 2012-03-11 09:54:47

+0

最上面的代码来自XML :: Twig。底层代码来自XML :: Parser,即超类。您没有向我们显示任何代码。你可能会做所有其他不好的事情。 – 2012-03-11 16:59:43