我正在解析以下XML,并从XML数据中获取IP地址。在访问$ region-> {'IpRange'}时,在ExtractXmlIps.pl第45行中将错误抛出为Not a ARRAY reference。有时Region不包含任何值。在这种情况下,我会收到此错误。当我添加“ if($ region && $ region-> {'IpRange'})”之类的支票时,它仍然抛出错误。
<?xml version="1.0" encoding="utf-8"?>
<IpAddresses xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Region Name="us" />
<Region Name="asia">
<IpRange Subnet="10.10.10.0/21" />
</Region>
</IpAddresses>
解析xml的代码:
getstore ( $urls[0], $file_path );
my $xml = new XML::Simple;
my $xml_data = $xml -> XMLin ( $file_path );
foreach my $region ( @{ $xml_data -> { 'Region' } } ) {
foreach my $ip ( @{ $region -> { 'IpRange' } } ) {
print $ip;
}
}
我为该区域和该区域内部添加了空检查。试图找到数组的长度,并添加了该检查。
答案 0 :(得分:3)
请查看XML :: Simple文档,当只有一个子元素时,它将以name => 'value'
而不是代码期望的name => [ 'value' ]
的形式返回。您可以更改
$xml_data = $xml -> XMLin ( $file_path );
到
$xml_data = $xml -> XMLin ( $file_path, ForceArray => 1 );
以便所有子元素都作为数组引用返回。
答案 1 :(得分:2)
这是不阅读文档的情况。使用strict mode。
use 5.010;
use XML::Simple qw(:strict);
my $xs = XML::Simple->new(ForceArray => 1, KeyAttr => []);
my $root = $xs->XMLin('so-56489347.xml');
foreach my $region (@{$root->{Region}}) {
foreach my $iprange (@{$region->{IpRange}}) {
say $iprange->{Subnet};
}
}
文档中还说使用XML::LibXML代替。
use 5.010;
use XML::LibXML qw();
my $root = XML::LibXML->load_xml(location => 'so-56489347.xml')->documentElement;
foreach my $region ($root->getChildrenByTagName('Region')) {
foreach my $iprange ($region->getChildrenByTagName('IpRange')) {
say $iprange->getAttribute('Subnet');
}
}
但是,有了该库后,您可以简单地使用XPath查找所需的XML元素,而且要短得多!
use 5.010;
use XML::LibXML qw();
my $doc = XML::LibXML->load_xml(location => 'so-56489347.xml');
for my $iprange ($doc->findnodes('//Region/IpRange[@Subnet]')) {
say $iprange->getAttribute('Subnet');
}