2013-10-01 47 views
0

我想解析我在此處具有的XML文件並打印internal元素的id屬性。Perl XML ::簡單用於解析內部節點

這是XML文件

<?xml version="1.0"?> 
<!DOCTYPE test SYSTEM "http://www.kegg.jp/kegg/xml/KGML_v0.7.1_.dtd"> 
<test name="A" > 
    <node id="11" name="test1" > 
     <internal id="111" name="A111"/> 
    </node> 
    <node id="12" name="B"> 
     <internal id="121" name="B121"/> 
     <internal id="122" name="B122"/> 

    </node> 
</test> 

這裏是代碼,這時候一個一個節點有兩個內部屬性

use strict; 
use warnings; 

use XML::Simple; 
use Data::Dumper; 

my $xml=new XML::Simple; 
my $doc=$xml->XMLin("test.xml",KeyAttr => ['id']); 

print Dumper($doc); 

foreach my $node (sort keys %{$doc->{node}}) { 
    print $doc->{node}->{$node}->{internal}->{id}."\n"; 
} 

這裏是翻斗車的樣子

$VAR1 = { 
     'name' => 'test1', 
     'node' => { 
       '11' => { 
         'name' => 'A', 
         'internal' => { 
             'name' => 'A111', 
             'id' => '111' 
            } 
         }, 
       '12' => { 
         'name' => 'B', 
         'internal' => { 
             '122' => { 
               'name' => 'B122' 
              }, 
             '121' => { 
               'name' => 'B121' 
              } 
            } 
         } 
       } 
    }; 
失敗
+0

@mpapec則結果爲111,122,它基本上省略了ID中的一個(當它是2個IDS) – shaq

+0

有許多關於如何解析可能有益KEGG XML文件PerlMonks相關的帖子。例如,[解析和XML文件](http://www.perlmonks.org/?node_id=989488),[解析XML使用LibXML](http://www.perlmonks.org/?node_id=1043959),[用SAX解析一個沒有根節點的XML文檔](http://www.perlmonks.org/?node_id=165318)。例如,在這裏也有一些,[使用XML :: Rules perl解析xml文件](http://stackoverflow.com/questions/17609381/parsing-xml-files-using-xmlrules-perl)。 – SES

回答

0

添加

ForceArray => [qw(node internal)] 

代碼:

my $doc = XMLin(\$xml, 
    ForceArray => [qw(node internal)], 
    KeyAttr => [qw(id)], 
); 

print(Dumper($doc)); 

my $nodes = $doc->{node}; 
for my $node_key (sort { $a <=> $b } keys %$nodes) { 
    my $node = $nodes->{$node_key}; 
    my $internals = $node->{internal}; 

    for my $internal_key (sort { $a <=> $b } keys %$internals) { 
     print("$internal_key\n"); 

     # my $internal = $internals->{$internal_key}; 
     # print("$internal->{name}\n"); 
    } 
} 
+0

好吧它沒有幫助,可能是我必須改變我訪問id的方式「以數組方式」 – shaq

+0

它使它始終爲'internal'返回一個散列值,而不是僅僅在某些時間。您必須更改您的代碼以迭代該散列。查看更新。 – ikegami

0

代碼:

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

use XML::Simple; 
use Data::Dumper; 

my $xml=new XML::Simple; 
my $doc=$xml->XMLin(&get_str(),ForceArray => ['internal'],KeyAttr => 'id'); 
print Dumper($doc); 

sub get_str { 
    return qq#<?xml version="1.0"?> 
<!DOCTYPE test SYSTEM "http://www.kegg.jp/kegg/xml/KGML_v0.7.1_.dtd"> 
<test name="A" > 
    <node id="11" name="test1" > 
     <internal id="111" name="A111"/> 
    </node> 
    <node id="12" name="B"> 
     <internal id="121" name="B121"/> 
     <internal id="122" name="B122"/> 

    </node> 
</test>#; 
} 

輸出:

$VAR1 = { 
     'name' => 'A', 
     'node' => { 
       '11' => { 
         'name' => 'test1', 
         'internal' => { 
             '111' => { 
               'name' => 'A111' 
              } 
            } 
         }, 
       '12' => { 
         'name' => 'B', 
         'internal' => { 
             '122' => { 
               'name' => 'B122' 
              }, 
             '121' => { 
               'name' => 'B121' 
              } 
            } 
         } 
       } 
    }; 

Reason

注1:'KeyAttr'的默認值是['name','key','id']。如果您不想摺疊輸入或展開輸出,則必須將此選項設置爲空列表以禁用該功能。注意2:如果你想使用這個選項,你也應該啓用ForceArray選項。如果沒有'ForceArray',單個嵌套元素將被捲成標量而不是數組,因此不會被摺疊(因爲只有數組被摺疊)。