2011-10-05 166 views
0

我有以下大型xml文件,其格式如下: 有人可以幫助我如何使用xml :: twig處理它?使用xml :: twig解析xml文件

<root > 
     <entity id="1" last_modified="2011-10-1"> 
     <entity_title> title</entity_title> 
     <entity_description>description </entity_description> 
     <entity_x> x </entity_x> 
     <entity_y> x </entity_y> 
     <entity_childs> 
      <child flag="1"> 
      <child_name>name<child_name> 
      <child_type>type1</child_type> 
      <child_x> some_text</child__x> 
      </child> 
      <child flag="1"> 
      <child_name>name1<child_name> 
      <child_type>type2</child_type> 
      <child_x> some_text</child__x> 
      </child> 
     <entity_sibling> 
      <family value="1" name="xc">fed</ext_ref> 
      <family value="1" name="df">ff</ext_ref> 
     </entity_sibling> 
    <\root> 


; 

我運行下面的代碼,並得到內存不足!

my $file = shift ||die $!; 

my $twig = XML::Twig->new(); 

my $config = $twig->parsefile($file)->simplify(); 

print Dumper($config); 
+0

XML ::簡單,但該文件是如此之大,並堅持perl的interpeter – smith

+0

你得到什麼錯誤消息(S)?發佈您嘗試過的代碼的相關代碼片段。 – 2011-10-05 21:33:35

+1

發佈您嘗試過的腳本。 – Dave

回答

1

是的,在XML :: Twig中沒有什麼魔力,如果你編寫$twig->parsefile($file)->simplify();那麼它會將整個文檔加載到內存中。恐怕你必須付出一些努力才能得到你想要的東西,並放棄其餘的東西。請參閱文檔頂部的Synopsys或 XML :: Twig 101部分以獲取更多信息。

這成爲一個常見問題,所以我已經添加blurb上面的模塊的文檔。

在你可能想在entity設定的處理程序(使用twig_handlers選項),如果你只是想提取數據,這種特殊情況下,過程中的每個實體,然後如果你正在更新的文件使用flush拋棄它,或者purge從中。

因此,代碼的結構應該是這樣的:

#!/usr/bin/perl 
use strict; 
use warnings; 

use XML::Twig; 

my $file = shift;  

my $twig=XML::Twig->new(twig_handlers => { entity => \&process_entity },) 
        ->parsefile($file); 

exit; 

sub process_entity 
    { my($t, $entity)= @_; 

    # do what you have to do with $entity 

    $t->purge; 
    }  
4

XML ::嫩枝能夠在兩種模式下運行,爲小型或大型文件。你說它很大,所以你想要在documentation synopsis中列出的第二種方法。

處理龐大文件的例子是這樣的:

# at most one div will be loaded in memory 
    my $twig=XML::Twig->new( 
    twig_handlers => 
     { title => sub { $_->set_tag('h2') }, # change title tags to h2 
     para => sub { $_->set_tag('p') }, # change para to p 
     hidden => sub { $_->delete;  }, # remove hidden elements 
     list => \&my_list_process,   # process list elements 
     div  => sub { $_[0]->flush;  }, # output and free memory 
     }, 
    pretty_print => 'indented',    # output will be nicely formatted 
    empty_tags => 'html',     # outputs <empty_tag /> 
         ); 
    $twig->flush;        # flush the end of the document 

所以我想你想使用該方法,而不是你目前正在使用標註爲只對小文件的一個。

+1

你可能想要在你的代碼中解析文件... – mirod