Anu2117
asked on
Convert xml to hash in perl
This is the continuation of
https://www.experts-exchange.com/questions/23837595/XML-generation-with-XML-Simple-XMLout.html
I was wondering if its possible to build a hash back from the xml that got generated. Will this hash match the original hash?
Basically, I wanted to build a hash from a string and convert the hash to xml format. This is working so far with the code below. Now I want to see if it's possible to build a hash(hash of hash) back from this xml and will it look same as the original hash.
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my @str = (";&EVENT[__nmi_0](nmi, THREAD => 0, TRIGGER => &TRIGGER[__nmi_0.trigger]( eom, LIP => 0x2020, SELF_CHECK => 'MUST_COMPLETE', THREAD => 0));",
";&EVENT[__psmi_1](psmi, THREAD => 0, TRIGGER => &TRIGGER[__retire_1](retir e, LIP => 0x203f, TRIGGER => &EVENT[__smi_1](smi, THREAD => 1, TRIGGER => &TRIGGER[__eom_1](eom, LIP => 0x203f, THREAD => 0))));",
";&EVENT[__psmi_0](psmi, THREAD => 0, TRIGGER => &TRIGGER[__psmi_0.trigger] (eom, LIP => 0x2000, SELF_CHECK => 'MUST_COMPLETE', THREAD => 0));" );
my %Event;
my %Pieces;
foreach (@str) {
%Pieces = ();
my $Cnt;
1 while s/\&(\w+)\[__([^\]]+)\]\(( \w+),\s+([ ^\(\)]+)\) /$Cnt++;$P ieces{$Cnt }=MakeHash ($1,$2,$3, $4);"$2:Su bHash{$Cnt }"/ge;
for my $piece (sort {$b <=> $a} keys %Pieces) {
while(my ($k, $v) = each %{$Pieces{$piece}}) {
if($v =~ /^(.*):SubHash{(\d+)}$/) {
$Pieces{$piece}->{$k}=$1;
$Pieces{$piece}->{$1}=$Pie ces{$2};
}
}
}
if(/^;(.*):SubHash{(\d+)}; $/) {
$Event{$1}=$Pieces{$2};
}
}
print XMLout(\%Event);
sub MakeHash {
return {lc($_[0])=> $_[2], split(/[,=>\s]+/, $_[3])};
}
sub XMLout {
my ($ref, $pre) = @_;
$pre='' unless defined($pre);
my $str='';
if(ref($ref) eq 'HASH') {
foreach my $k (sort keys %$ref) {
$str .= "$pre<param name=$k>\n";
if(ref($ref->{$k})) { $str .= XMLout($ref->{$k},"$pre\t" ); }
else { $str .= "$pre\t<value val=$ref->{$k} />\n"; }
$str .= "$pre</param>\n";
}
}
else {
die "Unsupported reference: " . ref($ref) . "\n";
}
return $str;
}
https://www.experts-exchange.com/questions/23837595/XML-generation-with-XML-Simple-XMLout.html
I was wondering if its possible to build a hash back from the xml that got generated. Will this hash match the original hash?
Basically, I wanted to build a hash from a string and convert the hash to xml format. This is working so far with the code below. Now I want to see if it's possible to build a hash(hash of hash) back from this xml and will it look same as the original hash.
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my @str = (";&EVENT[__nmi_0](nmi, THREAD => 0, TRIGGER => &TRIGGER[__nmi_0.trigger](
";&EVENT[__psmi_1](psmi, THREAD => 0, TRIGGER => &TRIGGER[__retire_1](retir
";&EVENT[__psmi_0](psmi, THREAD => 0, TRIGGER => &TRIGGER[__psmi_0.trigger]
my %Event;
my %Pieces;
foreach (@str) {
%Pieces = ();
my $Cnt;
1 while s/\&(\w+)\[__([^\]]+)\]\((
for my $piece (sort {$b <=> $a} keys %Pieces) {
while(my ($k, $v) = each %{$Pieces{$piece}}) {
if($v =~ /^(.*):SubHash{(\d+)}$/) {
$Pieces{$piece}->{$k}=$1;
$Pieces{$piece}->{$1}=$Pie
}
}
}
if(/^;(.*):SubHash{(\d+)};
$Event{$1}=$Pieces{$2};
}
}
print XMLout(\%Event);
sub MakeHash {
return {lc($_[0])=> $_[2], split(/[,=>\s]+/, $_[3])};
}
sub XMLout {
my ($ref, $pre) = @_;
$pre='' unless defined($pre);
my $str='';
if(ref($ref) eq 'HASH') {
foreach my $k (sort keys %$ref) {
$str .= "$pre<param name=$k>\n";
if(ref($ref->{$k})) { $str .= XMLout($ref->{$k},"$pre\t"
else { $str .= "$pre\t<value val=$ref->{$k} />\n"; }
$str .= "$pre</param>\n";
}
}
else {
die "Unsupported reference: " . ref($ref) . "\n";
}
return $str;
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
As Adam314 said, getting the perl hash from the XML is just:
my $hash = XMLin($filename); # $filename can also be a string
I would suggest looking at the XML::Simple documentation as there are quite a few useful options to both XMLin and XMLout.