2011-10-05 124 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