2017-07-23 14 views
7

Parsuję duże pliki XML (60 GB +) z XML::Twig i używam ich w skrypcie OO (łosia). Używam opcji twig_handlers do analizowania elementów, gdy tylko zostaną one wczytane do pamięci. Jednak nie jestem pewien, jak sobie poradzę z Elementem i Gałązką.Purge XML Twig wewnątrz podporządkowarki

Przed użyłem Moose (i zupełnie OO), mój skrypt wyglądał następująco (i działało):

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 
} 

A teraz chciałbym zrobić to w ten sposób.

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 
} 

Chodzi o to, że teraz widzę, że jestem brakuje przedmuchiwania fulltwig. Pomyślałem, że - w pierwszej wersji bez OO - oczyszczenie pomoże w oszczędzaniu pamięci: pozbycie się pełnej mocy tak szybko, jak tylko będę mógł. Jednak podczas korzystania z OO (i mający polegać na wyraźnej sub{} wewnątrz uchwytu) nie widzę w jaki sposób można oczyścić całą gałązkę ponieważ dokumentacja mówi, że

$ _ jest również ustawienie elementu, tak łatwo jest napisać Wozy inline jak

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

więc mówić o elemencie, który chcesz przetworzyć, ale nie fulltwig sama. Jak mogę to skasować, jeśli nie zostanie przekazany do podprogramu?

Odpowiedz

6

Handler wciąż dostaje pełną gałązkę, po prostu jej nie używasz (zamiast tego używasz _).

Jak się okazuje można jeszcze nazwać purge na patyk (który zwykle nazywamy „element”, lub elt w docs): $_->purge będzie działać zgodnie z oczekiwaniami, czyszczenie pełną gałązkę do bieżącego elementu w $ _ ;

Czystsze (IMHO) sposobem byłoby rzeczywiście dostać wszystkie parametry i oczyścić całą gałązkę 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

Ach, mój zły! Powinienem sprawdzić "@ _", żeby zobaczyć, co się dzieje. Dzięki! Czy jest jakiś minus/w górę oczyszczanie całej gałązki * po * robiłeś rzeczy z odciętą gałązką? Moje rozumowanie polegało na usunięciu go natychmiast po przycięciu elementu *, tak aby pamięć została wyczyszczona jak najszybciej. Mogę się mylić? Świetny moduł przy okazji, używamy go ** wszystkie ** czas! –

+1

Nie powinno to mieć żadnego znaczenia, kiedy się przeczyścisz. Najważniejsze jest odzyskanie pamięci przed rozpoczęciem analizowania następnego poddrzewa. I dzięki ;-) – mirod

+1

Byłoby to również dobrym przykładem użycia dla modułu curry. – simbabque