chinna_82
chinna_82

Reputation: 6403

Perl - Read XML

XML

<?xml version='1.0'?>
<employee>
<name>Smith</name>
<age>43</age>
<sex>M</sex>
<department role='manager'>Operations</department>
</employee>

Perl

use XML::Simple;
use Data::Dumper;
$xml = new XML::Simple;
foreach my $data1 ($data = $xml->XMLin("test.xml")) {
print Dumper($data1);
}

Above code managed to all the xml value like this.
Output

$VAR1 = {
          'department' => {
                            'content' => 'Operations',
                            'role' => 'manager'
                          },
          'name' => 'John Doe',
          'sex' => 'M',
          'age' => '43'
        };

How do I do, if I only want to get the role value. For this example I need to get Role => manager. Any advice or reference link is highly appreciated.

Upvotes: 1

Views: 237

Answers (3)

Miller
Miller

Reputation: 35198

So all you need is that value?

print $data->{department}{role};

Even though XML::Simple can do the job for simple xml reading, I'd recommend that you use a better module like XML::LibXML or XML::Twig:

use strict;
use warnings;

use XML::LibXML;

my $xml = XML::LibXML->load_xml(IO => \*DATA);

for my $role ($xml->findnodes('//@role')) {
    print $role->value;
}

__DATA__
<?xml version='1.0'?>
<employee>
<name>Smith</name>
<age>43</age>
<sex>M</sex>
<department role='manager'>Operations</department>
</employee>

Outputs:

manager

About XPaths

The power the modules XML::LibXML and XML::Twig comes in their implementation of XPath syntax. I used the minimal XPath needed to pull the data that you want '//@role' to demonstrate how it doesn't need to know the full tree structure like is needed for XML::Simple. That XPath basically just pulls the value of any "role" attribute at any level.

As ikegami pointed out, it would probably be wise to make the XPath more limiting, such as '//department/@role' or '//employee/department/@role'. Or even more likely, you'll iterate on all employees and then pull the desired data.

for my $employee ($xml->findnodes('//employee')) {
    print $employee->findvalue('//department/@role')
}

For further examples of XPaths, just check the w3schools link above or XPath Examples

Finally, to find additional ways of loading the DOM, just check out XML::LibXML::Parser

Upvotes: 4

wissem46
wissem46

Reputation: 403

There is a very helpful tool called XMLStarlet i used it to parse xml files with Perl and shell scripts. in your case : this command do the job :

xmlstarlet sel -t -m "/employee/department" -m "@role" -v . -n your_file_name.xml

you can assign the output to a variable :

your_variable =`xmlstarlet sel -t -m "/employee/department" -m "@role" -v . -n your_file_name.xml`

for documentation : have a look on this link : XMLStarlet Documentation

Upvotes: 0

mirod
mirod

Reputation: 16161

With XML::Twig:

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

XML::Twig->new( twig_handlers =>  # in the handler $_ is the department element
                  { department => sub { print $_->att( 'role'), "\n"; } })
         ->parsefile( 'test.xml');

Upvotes: 0

Related Questions