2012-03-10 64 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