2017-07-23 33 views
7

裏面我解析大型XML文件(60GB +)與XML::Twig,並在OO(麋鹿)腳本中使用它。我現在用的是twig_handlers的選擇,因爲他們讀入內存,儘快解析元素。但是,我不知道我如何處理元素和樹枝。清除XML小枝子處理

我用駝鹿之前(和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 
} 

現在我不喜歡這樣。

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 
} 

事情是,我現在看到我錯過了清除fulltwig。我想, - 在第一,非面向對象的版本 - 淨化將有助於節約內存:得到,只要我能擺脫fulltwig的。但是,使用OO(且依賴於處理器中明確sub{})時,我沒有看到,因爲文檔中說,

$ _也被設置爲元素,我可以怎樣清除全部樹枝,所以很容易寫內嵌處理器 像

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

所以他們談談你要處理的元素,但不是fulltwig本身。那麼,如果它沒有傳遞給子例程,我該如何刪除它?

回答

6

處理程序仍然得到完整的樹枝,你只是不使用它(使用$ _代替)。

事實證明,你仍然可以調用(在該文檔中,我通常所說的「元素」,或elt)上的樹枝purge$_->purge會按預期工作,淨化全樹枝上漲到目前的元素$ _ ;

一個清潔的(恕我直言)的方式將實際獲得所有的參數和expicitely清除全部樹枝:

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 
} 
+0

啊哈,是我不好!我應該檢查'@ _'來看看發生了什麼。謝謝!有隻有* *後你做的東西與切割樹枝清除全部樹枝中的任何缺點/上攻?我的推理是在切割*元素後立即清除它,以便儘快清除內存。我可能錯了?順便說一句,我們使用它**所有**時間! –

+1

清洗時應該沒有區別。最重要的是在開始分析下一個子樹之前回收內存。而感謝; - ) – mirod

+1

這也將是一個很好的用例咖喱模塊。 – simbabque