我是Perl的新手。我试图循环xml文件中的每个条目来执行任务,但它正在死于“第9行没有数组引用”。
我的脚本是
#!/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>
我想在每个条目中列出翻译地址。假设有很多这样的条目。请帮帮我。
答案 0 :(得分:1)
KeyAttr
选项的默认值为
KeyAttr => [qw( name key id )]
这意味着XML :: Simple将转换
[ { name => $name1, ... }, { name => $name2, ... }, ... ]
到
{ $name1 => { ... }, $name2 => { ... }, ... }
您可以使用以下选项获取您期望的结构。
KeyAttr => []
如果您希望只有一个条目时代码能够正常工作,请不要忘记提供以下选项:
ForceArray => [qw( entry )]
XML :: Simple的使用是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");
}
答案 1 :(得分: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,您将能够看到数据结构,并且您将看到哈希而不是您假设的数组。
答案 2 :(得分: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');
}