I’m having an issue accessing some nested data in an XML response using Perl/XML::Simple. An extract of the printed XML reply looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:SelectCmDeviceResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://schemas.cisco.com/ast/soap/">
<SelectCmDeviceResult xsi:type="ns1:SelectCmDeviceResult">
<TotalDevicesFound xsi:type="xsd:unsignedInt">3</TotalDevicesFound>
<CmNodes soapenc:arrayType="ns1:CmNode[3]" xsi:type="soapenc:Array" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<item xsi:type="ns1:CmNode">
<ReturnCode xsi:type="ns1:RisReturnCode">NotFound</ReturnCode>
<Name xsi:type="xsd:string">10.186.78.4</Name>
<NoChange xsi:type="xsd:boolean">false</NoChange>
<CmDevices soapenc:arrayType="ns1:CmDevice[0]" xsi:type="soapenc:Array"/>
</item>
<item xsi:type="ns1:CmNode">
<ReturnCode xsi:type="ns1:RisReturnCode">Ok</ReturnCode>
<Name xsi:type="xsd:string">10.186.78.68</Name>
<NoChange xsi:type="xsd:boolean">false</NoChange>
<CmDevices soapenc:arrayType="ns1:CmDevice[2]" xsi:type="soapenc:Array">
<item xsi:type="ns1:CmDevice">
<Name xsi:type="xsd:string">SEPD0574CF73FC0</Name>
<IpAddress xsi:type="xsd:string">10.186.79.41</IpAddress>
<DirNumber xsi:type="xsd:string">51251001-Registered,51251004-Registered,51251002-Registered</DirNumber>
<Class xsi:type="ns1:DeviceClass">Phone</Class>
<Model xsi:type="xsd:unsignedInt">404</Model>
<Product xsi:type="xsd:unsignedInt">303</Product>
<BoxProduct xsi:type="xsd:unsignedInt">0</BoxProduct>
Here is the code, which should parse the response and return the IpAddress values of the returned devices:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use XML::Simple;
use LWP;
use SOAP::Lite;
my $cucmip = "10.1.10.1";
my $axl_port = "8443";
my $user = "admin";
my $password = "password";
my $axltoolkit = "http://schemas.cisco.com/ast/soap/action/#RisPort#SelectCmDevice";
sub getDevIp {
my $message = "<?xml POST message>
my $url="https://$cucmip:$axl_port/realtimeservice/services/RisPort?wsdl";
my $ua = LWP::UserAgent->new;
my $header = new HTTP::Headers (
'Content-Type' => 'application/xml; charset=utf-8',
'SOAPAction' => 'http://schemas.cisco.com/ast/soap/action/#RisPort#SelectCmDevice',
);
my $req = HTTP::Request->new(POST => $url, $header, $message);
$req->authorization_basic($user,$password);
my $response = $ua->request($req);
my $xs = new XML::Simple(KeyAttr=>[]);
my $data = $xs->XMLin($response->content);
print $data->{'soapenv:Body'}->{'ns1:SelectCmDeviceResponse'}->{'SelectCmDeviceResult'}->{'CmNodes'}->{'item'}->[0]->{'CmDevices'}->{'item'}->[0]->{'IpAddress'}->{'content'};
}
getDevIp();
This is basically what you have.
You are trying to access with
The values that do not exist are created by perl on first access (this is called autovivification) and initialized
undef.That is the reason for your warning.