2015-12-16 47 views
0

我是Perl新手。我正在嘗試爲xml文件中的每個條目循環執行任務,但它正在死於「不是第9行的數組引用」。非數組引用導航XML ::簡單結構

我的劇本是

#!/usr/bin/perl 
# use module 
use XML::Simple; 
# create object 
$xml = new XML::Simple; 
# read XML file 
$data = $xml->XMLin("data.xml"); 
# access XML data 
foreach my $entry (@{$data->{entry}}){ 
print $entry->{'source-translation'}->{'static-ip'}-{'translated-address'}; 
} 

我的XML文件中的數據是

<?xml version="1.0"?> 
<config version="6.0.0" urldb="paloaltonetworks"> 
    <entry name="DROP NAT"> 
    <source-translation> 
     <static-ip> 
     <bi-directional>yes</bi-directional> 
     <translated-address>192.91.75.129</translated-address> 
     </static-ip> 
    </source-translation> 
    <to> 
     <member>Outside</member> 
    </to> 
    <from> 
     <member>DROP</member> 
    </from> 
    <source> 
     <member>192.91.66.72</member> 
    </source> 
    <destination> 
     <member>any</member> 
    </destination> 
    <service>any</service> 
    <description>NAT for DROP FTP Server</description> 
    <to-interface>ethernet1/1</to-interface> 
    <nat-type>ipv4</nat-type> 
    </entry> 
    <entry name="SDROP NAT"> 
    <source-translation> 
     <static-ip> 
     <bi-directional>yes</bi-directional> 
     <translated-address>192.91.75.154</translated-address> 
     </static-ip> 
    </source-translation> 
    <to> 
     <member>Outside</member> 
    </to> 
    <from> 
     <member>DROP</member> 
    </from> 
    <source> 
     <member>192.91.66.79</member> 
    </source> 
    <destination> 
     <member>any</member> 
    </destination> 
    <service>any</service> 
    <description>NAT for SFTP server SDROP</description> 
    <to-interface>ethernet1/1</to-interface> 
    <nat-type>ipv4</nat-type> 
    </entry> 
</config> 

我想在每個條目中列出轉換地址。假設有很多像這樣的條目。請幫幫我。

+1

'使用數據::自卸車;打印Dumper $ data;' –

+4

您的腳本只有11行。哪一條是第13行? – serenesat

+2

注意:在''translated-address''前面有一個減號,可能你的意思是' - >'? –

回答

0

如您所述$data->{entry}不是數據結構中的數組引用;它是一個哈希引用。

檢查下面的腳本,它訪問的散列數據:

#!/usr/bin/perl 
use v5.10; use strict; use warnings; 
use XML::Simple; 

my $xml = new XML::Simple; 
my $data = $xml->XMLin("data.xml"); 
for my $entry (keys %{$data->{entry}}){ 
    say $data->{entry}->{$entry}->{'source-translation'}->{'static-ip'}->{'translated-address'}; 
} 

而作爲Сухой27指出;如果你使用Data :: Dumper,你將能夠看到數據結構,你會看到散列而不是假定的數組。

1

KeyAttr選項的默認值是

KeyAttr => [qw(name key id)] 

這意味着,XML ::簡單的將其轉換

[ { name => $name1, ... }, { name => $name2, ... }, ... ] 

{ $name1 => { ... }, $name2 => { ... }, ... } 

您可以使用下面的選項得到你期望的結構。

KeyAttr => [] 

不要忘了,如果你想你的代碼工作的時候只有一個入口的存在是爲了還提供下列選項:

ForceArray => [qw(entry)] 

使用XML ::簡單的是discouraged,甚至通過它自己的文檔。


XML ::的libxml解決方案:

use XML::LibXML qw(); 
my $parser = XML::LibXML->new(); 
my $doc = $parser->parse_file('data.xml'); 
for my $node ($doc->findnodes(
    '/config/entry/source-translation/static-ip/translated-address' 
)) { 
    print($node->textContent(), "\n"); 
} 
0

這裏是你的問題:

use XML::Simple; 

XML::Simple誤導你。這並不簡單。除非你絕對沒有選擇(你可能會這麼做 - 它不是核心),那麼使用另一個解析器會減少痛苦。

像:

use XML::Twig; 
print $_ -> trimmed_text,"\n" for XML::Twig -> new -> parsefile ('data.xml') -> get_xpath ('//translated-address'); 

擴張到這更像是:

use strict ; 
use warnings; 
my $twig = XML::Twig -> new; 
$twig -> parsefile ('data.xml'); 
foreach my $entry ($twig -> findnodes ('//entry')) { 
    print $entry -> first_child('source-translation') -> first_child('static-ip') -> first_child_text('translated-address'); 
}