GRD GRD - 4 years ago 156
Perl Question

Which syntaz is better XML::Simple or XML::Twig

I was running a Perl script and I encountered the following result, instead of the answer I expected.

input HASH(0x17268bb0)
input HASH(0x172b3300)
input HASH(0x172b32a0)

Can anyone say what this is and how to rectify it?

This is my XML file here

<Top name="ri_32">
<Module name="ALU">
<input name="power_control_bus"/>
<bidirection name="address_bus"/>
<Module name="Power_control">
<input name="cpu_control_bus"/>
<output name="power_control_bus"/>
<bidirection name="address_bus"/>
<input name="address"/>
<input name="clock"/>
<input name="data_in"/>
<output name="data_out"/>
<bidirection name="control"/>

I'm writing a Perl script which can be converted into a specific requirement (.v, .sv file)

use strict;

use XML::Simple;

use Data::Dumper;

my $xml_root = XMLin( './simodule.xml' );
my $root_top = $xml_root->{Top};
my $mod = $root_top->{Module};

print "Top $root_top->{name}\n";

my $top_in = $root_top->{input};
foreach my $namein ( keys %$top_in ) {
print " input $top_in->{$namein}\n";

my $top_ou = $root_top->{output};
foreach my $nameou ( keys %$top_ou ) {
print " output $top_ou->{$nameou}\n";

my $top_bi = $root_top->{bidirection};
foreach my $namebi ( keys %$top_bi ) {
print " bidirection $top_bi->{$namebi}\n";


Top risc_32
input HASH(0x172b3300)
input HASH(0x172b32a0)
input HASH(0x17268bb0)
output data_out
bidirection control

Expected output

input address
input clock
input data_in
output data_out
bidirection control

Answer Source

You've made your task more difficult for yourself by using one of the most deceitful modules on CPAN. XML::Simple isn't simple.

But it's docs also suggest not using it: Why is XML::Simple "Discouraged"?

So - how about instead, XML::Twig:

#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;

#$twig now contains our XML data structure. 
my $twig = XML::Twig->new->parsefile('simodule.xml'); 

#fetch a value with an xpath expression - ./Top
#then extract the attribute 'name' from this node. 
print "Top ", $twig->get_xpath( './Top', 0 )->att('name'), "\n";
#iterate all 'input' elements beneath "Top":
#note - single argument to "get_xpath" means all of them in a list. 
foreach my $input ( $twig->get_xpath('./Top/input') ) {
    #retrieve from each their name attribute (and print) 
    print "input ", $input->att('name'), "\n";

#locate the 'output' and 'bidirection' nodes within the tree, and fetch
#their name attribute. 
print "output ", $twig -> get_xpath( './Top/output',0) -> att('name'),"\n";
print "bidirection ", $twig -> get_xpath( './Top/bidirection',0) -> att('name'),"\n";

We use XML::Twig which makes use of get_xpath to specify an XML path. We also use att to retrieve a named attribute. You could use iterators such as first_child and children if you prefer though:

#Top element is below the root - we create a reference to it $top
my $top = $twig->root->first_child('Top');
#From this reference, fetch the name attribute. 
print "Top ", $top->att('name'), "\n";
#get children of Top matching 'input' and iterate
foreach my $input ( $top -> children('input') ) {
    #print attribute called 'name'. 
    print "input ", $input->att('name'), "\n";
#Find a child below Top called 'output' and retrieve 'name' attribute. 
print "output ", $top -> first_child('output') -> att('name'),"\n";
#as above. 
print "bidirection ", $top -> first_child('bidirection') -> att('name'),"\n";

These are doing the same thing - personally I like xpath as a way of navigating XML but that's a matter of taste. (It lets you do all sorts of things like specify a path with embedded attributes, that kind of thing - moot point in this example though).

Given your input XML, both produce:

Top ri_32
input address
input clock
input data_in
output data_out
bidirection control

it skips the nested hashes for ALU and Power_Control because your original code appears to.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download