2014-07-10 25 views
-1

我有一個巨大的XML文件只我在這裏粘貼部分在陣列節省:比較和提取屬性,並用perl嫩枝

<List NAME="ANDREW" ENROLED="2" FEE="640" CONFORMATION="I"> 
<DATA> 
    <HOUSE> 
    <PRIMARY GROUP_ID="37496" SECTION="A"/> 
    <PRIMARY GROUP_ID="37496" SECTION="B"/> 
    </HOUSE> 
    </DATA> 
</List> 
<List NAME="SAM" ENROLED="4" FEE="640" CONFORMATION="O"> 
    <DATA> 
    <HOUSE> 
    <PRIMARY GROUP_ID="36816" SECTION="A"/> 
    <PRIMARY GROUP_ID="36816" SECTION="B"/> 
    </HOUSE> 
    </DATA> 
</List> 
    <List NAME="MATHEW" ENROLED="3" FEE="467" CONFORMATION="I"> 
<DATA> 
    <HOUSE> 
    <PRIMARY GROUP_ID="37436" SECTION="A"/> 
    <PRIMARY GROUP_ID="37436" SECTION="B"/> 
    </HOUSE> 
    </DATA> 
</List> 
<List NAME="RAY" ENROLED="1" FEE="982" CONFORMATION="O"> 
    <DATA> 
    <HOUSE> 
    <PRIMARY GROUP_ID="36892" SECTION="A"/> 
    <PRIMARY GROUP_ID="36892" SECTION="B"/> 
    </HOUSE> 
    </DATA> 
</List> 

我使用的XML ::嫩枝

我要檢查是否「CONFORMATION」是我然後獲得「FEE」和「GROUP_ID」,並存儲在單獨的數組 ,如果「Conformation」是「O」,則獲得「FREE」和「GROUP_ID」並將它們存儲在不同的數組中。

use XML::Twig; 

my $filename = 'report2.txt'; 

open($fh, '>', $filename); 

my $twig = new XML::Twig(
    twig_roots => { 
     "List"     => \&add, 
     "List/DATA/HOUSE/PRIMARY" => \&update 
     } 
); 
$twig->parsefile("file.xml"); 

#$twig->print; 

sub add { 
    my ($twig, $add) = @_; # handlers params are always 
    $cond = $add->att('CONFORMATION'); 
    $cond2 = $add->att('FEE'); 

    if ($cond == 'I') { 
     sub update { 
      my ($twig, $update) = @_; 
      $check = $update->att('GROUP_ID'); 
      print $fh " GROUP_ID :$check "; 
     } 
    } elsif ($cond == 'O') { 
     sub update { 
      my ($twig, $update) = @_; 
      $check = $update->att('GROUP_ID'); 
      print $fh " GROUP_ID :$check "; 
     } 
     print $fh "CONFORMATION=$cond \n GROUP_ID : $cond2"; 
    } 
} 
close $fh; 
print "done\n"; 

現在我只是試圖在日誌中打印他們,所以我可以移動。 但被搞砸了。

請幫助我開始PERL 我的代碼是lyke這是打印所有這些,但不是按順序。

回答

1

好的,首先 - 移動updateadd子。這太骯髒了。

XML :: Twig致力於讓'處理程序''啓動'來解析XML代碼段。這是一個處理大文件的非常輕量級的方式,因爲XML的常見問題是它真的是內存飢餓。

雖然你正在過度複雜化。

#!/usr/bin/perl 

use strict; 
use warnings; 

use XML::Twig; 

sub process_list { 
    my ($twig, $list) = @_; 
    my $conformation = $list -> att('CONFORMATION'); 

    my $fee = $list -> att ('FEE'); 
    foreach my $primary ($list -> first_child ('DATA') -> first_child ('HOUSE') -> children()) 
    { 
     my $group_id = $primary -> att ('GROUP_ID'); 
     print "$conformation, $fee, $group_id\n"; 
     ### here you have the information you need to do the rest of your processing. 
    } 

} 

my $parser = XML::Twig -> new ('twig_handers' => { 'List' => \&process_list}); 

$parser -> parsefile ($xml_file); 

每次解析器看到「List」元素時都會觸發'handler',然後您可以提取所需的子元素和屬性。 children給出了要循環的元素列表。

+0

嗨,感謝您的回覆。 雖然我正在運行腳本它正在打印兩個值,但之後它的說法不能調用未定義值的方法「first_child」.. – user3805574

+0

該錯誤意味着'first_child'方法沒有任何匹配的東西。那是不是有一個沒有定義'DATA'或'HOUSE'的XML塊?無論哪種方式 - 這是你可能不得不調整你的代碼陷阱,因爲它走了。 – Sobrique

+0

嗨,感謝您的回覆。 當我打印某些值後說我不能在未定義的值上調用方法「first_child」時運行腳本。因爲也有其他實體可用不同的標題名稱,所以如何得到這一點。 – user3805574