Slim Baccar
Slim Baccar

Reputation: 21

Perl script to parse XML using XML::Simple

I am trying to parse the following XML. The problem is I get nothing in the output:

XML file:

<response>
  <response-name>SendUnitaryResponse</response-name>
    <params>
        <request-status>OK</request-status>
        <unitary-request-id>B4004A3E</unitary-request-id>
    </params>
</response>

Script:

use XML::Simple;
use Data::Dumper;
my $access = XMLin('C:\Users\s.baccar\Desktop\access.log');
print $access->{response}->{response-name};

Upvotes: 2

Views: 702

Answers (3)

Dre
Dre

Reputation: 4329

In addition to what other people have said, please use strict; ( and use warnings; )

If I add those to your script, I get:

Bareword "response" not allowed while "strict subs" in use at x.pl line 8.
Bareword "name" not allowed while "strict subs" in use at x.pl line 8.

( Note that line 8 is print $access->{response}->{response-name}; )

That line is effectively being turned into print $access->{response}->{0};

You need to use 'response-name'.

Upvotes: 1

Sobrique
Sobrique

Reputation: 53478

XML::Simple - isn't. It's for simple XML.

In it's documentation it says:

The use of this module in new code is discouraged. Other modules are available which provide more straightforward and consistent interfaces.

Instead, I like XML::Twig (other options exist):

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig; 

my $xml = q{<response>
  <response-name>SendUnitaryResponse</response-name>
    <params>
        <request-status>OK</request-status>
        <unitary-request-id>B4004A3E</unitary-request-id>
    </params>
</response>};

my $twig_parser = XML::Twig -> new -> parse ( $xml );
#in XML::Twig - root is the 'top' node, e.g. <response> in this case. 
print $twig_parser -> root -> first_child_text('response-name');

This also works if you give it a filename:

my $twig_parser = XML::Twig -> new -> parsefile ( 'C:\Users\myuser\Documents\test.xml' );
print $twig_parser -> root -> first_child_text('response-name');

Upvotes: 1

TobyLL
TobyLL

Reputation: 2296

As Sobrique points out, XML::Simple isn't that simple. In this case, it removes the root element (<response>), which is why your print statement fails. You can either change your print:

print $access->{response-name};

...or tell XML::Simple to keep the root element:

my $access = XMLin('C:/Users/s.baccar/Desktop/access.log', KeepRoot => 1);

...or best of all, use a different module.

Upvotes: 3

Related Questions