2013-09-30 3 views
5

나는 그것을 노드 중 하나가 2 그래픽을 가지고 있기 때문에 나는 붙어 다음 코드를 사용하여 간단한 XML을 사용하여 유리체에펄 XML

<?xml version="1.0"?> 
<!DOCTYPE pathway SYSTEM "http://www.kegg.jp/kegg/xml/KGML_v0.7.1_.dtd"> 
<pathway name="path:ko01200" org="ko" > 
    <entry id="1" > 
     <graphics name="one" 
      type="circle" /> 
    </entry> 
    <entry id="7" > 
     <graphics name="one" 
      type="rectangle" /> 
     <graphics name="two" 
      type="rectangle"/> 
    </entry> 
</pathway> 

피곤 다음 XML 파일이 집단. 그래서 그것은 불평합니다. 나는 그래픽 요소에 대해 또 다른 foreach 루프를 가져야한다고 가정하지만 진행 방법을 모른다. 여기

use strict; 
use warnings; 
use XML::Simple; 
use Data::Dumper; 

my $xml=new XML::Simple; 
my $data=$xml->XMLin("file.xml",KeyAttr => ['id']); 
print Dumper($data);  
foreach my $entry ( keys %{$data->{entry}}) { 
    print $data->{entry}->{$entry}->{graphics}->{type}."\n";    
} 

그래서 graphics 노드가, 때로는 자식 요소의 수에 따라 때로는 배열 해시, 그것은 strict mode 수 있도록 사용자에게 달려 있기 때문에

$VAR1 = { 
     'entry' => { 
       '1' => { 
         'graphics' => { 
             'name' => 'one...', 
             'type' => 'circle' 
            } 
         }, 
       '7' => { 
         'graphics' => [ 
             { 
             'name' => 'one', 
             'type' => 'rectangle' 
             }, 
             { 
             'name' => 'two', 
             'type' => 'rectangle' 
             } 
            ] 
         } 
       }, 
     'org' => 'ko', 
     'name' => 'path:ko01200' 
    }; 
circle 
Not a HASH reference at stack.pl line 12. 

답변

7

XML::Simple 일관성이 부족 코드의 결과이다.

XMLin("file.xml",KeyAttr => ['id'], ForceArray => [ 'graphics' ]); 
:

for my $entry (keys %{$data->{entry}}) { 

    my $graphics = $data->{entry}{$entry}{graphics}; 
    $graphics = [ $graphics ] if ref $graphics eq "HASH"; 
    print "$_->{type}\n" for @$graphics; 
} 

XML::LibXML

을 확인하시기 바랍니다 또는 @RobEarl 사용을 ForceArray 매개 변수를 제안, XML 파싱을위한 더 나은 모듈이 있습니다