Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert XML to Perl Hash

Tags:

xml

perl

For the below XML structure, I'm trying to get a corresponding Perl Hash array

<root>
  <ref name="abc_sia_%version1.ref%">
    <func envname = "test01" objectdir = "/home/pv66" base="default_771"/>
  </ref>
</root>

I am able to turn it into a perl hash using:

my $xml = new XML::Simple;
my $data = $xml->XMLin("/home/pv66", ForceArray => 1, KeyAttr => { ref => "name"});
print Dumper ($data);

From which the hash turns out to be:

$VAR1 = {
           'ref' => {
                       'abc_sia_%version1.ref' => {
                                                      'func' => [
                                                                  {
                                                                   'envname' => 'test01',
                                                                   'objectdir' => '/home/pv66',
                                                                   'base' => 'default_771'
                                                                  }
                                                                ]       
                                                  }
                    }
         };

Although I need to remove the upper reference, basically I want the hash to look like:

$VAR1 = {
           'abc_sia_%version1.ref' => {
                                         'func' => [
                                                     {
                                                        'envname' => 'test01',
                                                        'objectdir' => '/home/pv66',
                                                        'base' => 'default_771'
                                                     }
                                                   ]       
                                       }
        };

Is there any way by which I can transform the hash??

like image 297
Pv66 Avatar asked Nov 01 '25 12:11

Pv66


1 Answers

The docs for XML::LibXML can be a bit terse for beginners. I recommend Grant's tutorial instead.

XML::LibXML doesn't have a single "make a data structure from this XML document" method. As XML::Simple shows, that approach would be too fragile to be useful. Instead, you can walk the DOM yourself to extract whatever data you want into your data structure. Personally, I'm a fan of using XPath expressions to identify what I want.

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

use Data::Dumper;
use XML::LibXML;

# Here, I've loaded the XML from the DATA filehandle
# (at the end of the source file). Other options are
# available.
my $dom = XML::LibXML->load_xml(IO => \*DATA);

my $data;

# Look for all '/root/ref' nodes...
for my $ref ($dom->findnodes('/root/ref')) {
  # Get the name of the ref node
  my $key = $ref->findvalue('./@name');
  my @funcs;
  # Look for all of the 'func' nodes below this ref node
  for my $func ($ref->findnodes('./func')) {
    my $func_data;
    # For each attribute we're interested in...
    for (qw[envname objectdir base]) {
      # Get the value of the attribute
      $func_data->{$_} = $func->findvalue("./\@$_");
    }
    push @funcs, $func_data;
  }
  $data->{$key}{func} = \@funcs;
}

say Dumper $data;

__DATA__
<root>
  <ref name="abc_sia_%version1.ref%">
    <func envname = "test01" objectdir = "/home/pv66" base="default_771"/>
  </ref>
</root>
like image 54
Dave Cross Avatar answered Nov 04 '25 07:11

Dave Cross



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!