6 Replies - 6972 Views - Last Post: 24 May 2012 - 08:19 AM

#1 shak4031  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 4
  • Joined: 22-May 12

Trouble parsing XML via perl

Posted 22 May 2012 - 10:25 AM

I am trying to parse an XML output and am getting errors when attempting to target elements of the XML data. XML Data looks like below:

'<?xml version="1.0" encoding="utf-8"?>
<ArrayOfDeviceInformation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="https://netinfo.ti.citigroup.net/">
  <DeviceInformation>
    <DeviceId>73405</DeviceId>
    <DeviceName>rrdc-test-2811 Test</DeviceName>
    <IPAddress>196.185.254.196</IPAddress>
    <Status>Operational</Status>
    <autoReady>0</autoReady>
    <LBCode>RDC</LBCode>
    <REMSCode>13609</REMSCode>
    <BuildingName>Dale Data Centre</BuildingName>
    <Address>55 Jack Street1</Address>
    <City>City</City>
    <PostalCode>SE13 7EY</PostalCode>
    <County />
    <Country>United Kingdom</Country>
    <Region>WESTERN EUROPE</Region>
  </DeviceInformation>
</ArrayOfDeviceInformation>'


my $CreateVTWS   = "https://notis-devel.eur.nsroot.net/NOTIS/anonaccess/WorkingHours.asmx/GetDevicesByLoopBackIP?DeviceLoopbackIP=196.185.254.196";
   printLog( "$CreateVTWS\n" );
   
    my $agent = LWP::UserAgent->new;
    eval {
        $response = $agent->get( $CreateVTWS );
    };

    if ($@)
    {
         printLog( "An error occurred ($@)\n");
         printLog( Data::Dumper->Dumper($response));
         die "Calling NetInfo failed.";
    }

    my $content = $response->content;
    print  Dumper($content) ."\n";

    my $xmlResp = XMLin($content);
    print Dumper($xmlResp) ."\n";
    print $xmlResp->{DeviceInformation}->{DeviceName} ."\n";



Error Output:
"Not an ARRAY reference at"

This post has been edited by JackOfAllTrades: 22 May 2012 - 02:09 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Trouble parsing XML via perl

#2 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6064
  • View blog
  • Posts: 23,520
  • Joined: 23-August 08

Re: Trouble parsing XML via perl

Posted 22 May 2012 - 02:10 PM

Moved to Perl
Was This Post Helpful? 0
  • +
  • -

#3 dsherohman  Icon User is offline

  • Perl Parson
  • member icon

Reputation: 226
  • View blog
  • Posts: 654
  • Joined: 29-March 09

Re: Trouble parsing XML via perl

Posted 23 May 2012 - 05:21 AM

Can you provide a runnable, self-contained program which demonstrates the problem you're having? I suspect that the actual error is someplace other than in the code fragment you posted, since I don't see anyplace that's attempting to use an array reference and you cut off the error message before it stated where Perl thought the problem was.

Here's an example of an appropriate "runnable, self-contained program" which I put together based on what you posted (although it works just fine, so it's not much help in finding the cause of your error :D ):
#!/usr/bin/env perl

use strict;
use warnings;
use 5.010;

use XML::Simple;

my $xml = join '', <DATA>;
my $tree = XMLin($xml);

say $tree->{DeviceInformation}->{DeviceName};

__DATA__
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfDeviceInformation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  <DeviceInformation>
    <DeviceId>73405</DeviceId>
    <DeviceName>rrdc-test-2811 Test</DeviceName>
    <IPAddress>196.185.254.196</IPAddress>
    <Status>Operational</Status>
    <autoReady>0</autoReady>
    <LBCode>RDC</LBCode>
    <REMSCode>13609</REMSCode>
    <BuildingName>Dale Data Centre</BuildingName>
    <Address>55 Jack Street1</Address>
    <City>City</City>
    <PostalCode>SE13 7EY</PostalCode>
    <County />
    <Country>United Kingdom</Country>
    <Region>WESTERN EUROPE</Region>
  </DeviceInformation>
</ArrayOfDeviceInformation>


Was This Post Helpful? 0
  • +
  • -

#4 shak4031  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 4
  • Joined: 22-May 12

Re: Trouble parsing XML via perl

Posted 23 May 2012 - 08:08 AM

Thank you for the reply, i was able to get the program to work. What i am looking for is help with how to deal with multiple records in the XML. How to get all the "DeviceName"'s and "DeviceID"'s when there are multiple records. I am able to use the index to target one but i don't know how to determine how many records there are.

#!/usr/bin/env perl  

use strict;  
use warnings;  
use 5.010;  
use XML::Simple;  

my $xml = join '', <DATA>;  

my $tree = XMLin($xml);  

say $tree->{DeviceInformation}->[0]->{DeviceName};  

__DATA__  

<?xml version="1.0" encoding="utf-8"?>  
<ArrayOfDeviceInformation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  <DeviceInformation>
    <DeviceId>96989</DeviceId>
    <DeviceName>snoa449-acc02-6509</DeviceName>
    <IPAddress>192.166.45.9</IPAddress>
    <Status>Operational</Status>
    <autoReady>0</autoReady>
    <LBCode>A448</LBCode>
    <REMSCode>12492</REMSCode>
    <BuildingName />
    <Address>Tordenskioldsgate 8-10, Po Box 1481 Vika</Address>
    <City>Oslo</City>
    <PostalCode>N-0116</PostalCode>
    <County />
    <Country>Norway</Country>
    <Region>WESTERN EUROPE</Region>
  </DeviceInformation>
  <DeviceInformation>
    <DeviceId>96859</DeviceId>
    <DeviceName>snoa448-acc02-6509</DeviceName>
    <IPAddress>169.166.79.6</IPAddress>
    <Status>Operational</Status>
    <autoReady>0</autoReady>
    <LBCode>A448</LBCode>
    <REMSCode>12492</REMSCode>
    <BuildingName />
    <Address>Tordenskioldsgate 8-10, Po Box 1481 Vika</Address>
    <City>Oslo</City>
    <PostalCode>N-0116</PostalCode>
    <County />
    <Country>Norway</Country>
    <Region>WESTERN EUROPE</Region>
  </DeviceInformation>
</ArrayOfDeviceInformation>


Was This Post Helpful? 0
  • +
  • -

#5 shak4031  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 4
  • Joined: 22-May 12

Re: Trouble parsing XML via perl

Posted 23 May 2012 - 10:26 AM

I was able to make it work.

#!/usr/bin/env perl    

use strict;    

use warnings;    

use 5.010;    

use XML::Simple;    
 
my $xml = join '', <DATA>;    
   
# create object
    $xs1 = new XML::Simple (KeyAttr=>[]);

    # read XML data
    my $xmlResp = $xs1->XMLin($xml);

    # dereference hash ref
    # access <DeviceInformation> array
    foreach $e (@{$xmlResp->{DeviceInformation}})
    {
        print "Devicename: ".$e->{DeviceName}, "\n";
        print "DeviceID: ".$e->{DeviceId}, "\n";
    }

__DATA__    
<?xml version="1.0" encoding="utf-8"?>    
<ArrayOfDeviceInformation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
 <DeviceInformation>  
  <DeviceId>96989</DeviceId>  
  <DeviceName>snoa449-acc02-6509</DeviceName>  
  <IPAddress>192.166.45.9</IPAddress>  
  <Status>Operational</Status>  
  <autoReady>0</autoReady>  
  <LBCode>A448</LBCode>  
  <REMSCode>12492</REMSCode>  
  <BuildingName />  
  <Address>Tordenskioldsgate 8-10, Po Box 1481 Vika</Address>  
  <City>Oslo</City>  
  <PostalCode>N-0116</PostalCode>  
  <County />  
  <Country>Norway</Country>  
  <Region>WESTERN EUROPE</Region>  
 </DeviceInformation>  
 <DeviceInformation>  
  <DeviceId>96859</DeviceId>  
  <DeviceName>snoa448-acc02-6509</DeviceName>  
  <IPAddress>169.166.79.6</IPAddress>  
  <Status>Operational</Status>  
  <autoReady>0</autoReady>  
  <LBCode>A448</LBCode>  
  <REMSCode>12492</REMSCode>  
  <BuildingName />  
  <Address>Tordenskioldsgate 8-10, Po Box 1481 Vika</Address>  
  <City>Oslo</City>  
  <PostalCode>N-0116</PostalCode>  
  <County />  
  <Country>Norway</Country>  
  <Region>WESTERN EUROPE</Region>  
 </DeviceInformation>  
</ArrayOfDeviceInformation> 



Output:

Devicename: snoa449-acc02-6509
DeviceID: 96989
Devicename: snoa448-acc02-6509
DeviceID: 96859
Was This Post Helpful? 2
  • +
  • -

#6 dsherohman  Icon User is offline

  • Perl Parson
  • member icon

Reputation: 226
  • View blog
  • Posts: 654
  • Joined: 29-March 09

Re: Trouble parsing XML via perl

Posted 24 May 2012 - 02:34 AM

Glad to see you figured it out!

One thing that may trip you up, though: If there's only one DeviceInformation record in the input, this code will die on the line foreach my $e (@{$xmlResp->{DeviceInformation}}) with the error "Not an ARRAY reference". There are two basic ways to deal with this:

1) The easy way:
my $xmlResp = $xs1->XMLin($xml, forcearray => [qw( DeviceInformation )] );


Passing the additional "forcearray" parameter to XMLin will force the parser to return DeviceInformations as an array, even if there's only one of them.

2) The explicit way:
my @devices = ref $xmlResp->{DeviceInformation} eq 'ARRAY'
  ? @{$xmlResp->{DeviceInformation}}
  : ( $xmlResp->{DeviceInformation} );
foreach my $e (@devices)


This checks to see whether the it's dealing with an array of DeviceInformations or just one and puts it into @devices by the correct method, then loops over @devices instead of directly over $xmlResp->{DeviceInformation}.

For this case, since #1 is available, I would recommend going that route. The main reason I included #2 is because it can always be used when you have data which could contain either a single item or a reference to an array of items, while #1 relies on the data's source to provide an option to always get arrays, even for a single item.
Was This Post Helpful? 1
  • +
  • -

#7 shak4031  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 4
  • Joined: 22-May 12

Re: Trouble parsing XML via perl

Posted 24 May 2012 - 08:19 AM

Thank you for the save, most of my responses would have been a single record. I will employ option 1 that ou recommended.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1