use strict;
use warnings;
my $tab = " ";
my %refs_seen;
my %dispatch =
(
# scalar
'' => sub { my ( $element, $level ) = @_;
print $tab x $level, $element // "UNDEF", "\n";
},
'HASH' => sub { my ( $element, $level ) = @_;
print $tab x $level++, "\n";
for my $key (keys %{$element}) {
print $tab x $level, "\n";
structure_to_xml( $element->{$key}, $level+1 );
print $tab x $level, "\n"
}
print $tab x --$level, "\n";
},
'ARRAY' => sub { my ( $element, $level ) = @_;
print $tab x $level, "\n";
structure_to_xml( $_, $level+1 ) for @{$element};
print $tab x $level, "\n";
},
'default' => sub { my ( $element, $level ) = @_;
print $tab x $level, "\n"
},
);
# operates on references
sub structure_to_xml {
my ( $element, $level ) = @_;
if( ref $element ) {
if( exists $refs_seen{$element} ) {
print $tab x $level, "\n";
return;
} else {
$refs_seen{$element} = 1;
}
}
&{ $dispatch{ ref($_[0]) } // $dispatch{'default'} }(@_);
}
# here comes an example for using it
use XML::Simple;
# enable looking into XML::Simple objects
$dispatch{'XML::Simple'} = $dispatch{HASH}; # comment out if you do not want to see internals
my $xml = XML::Simple->new();
sub somesub { }
my $hashref;
$hashref->{self} = $hashref;
my $var = { "0x55555555" => { "0x55555555" => [ ["0xAAAAAAAA", "0x9"], ],
"0xAAAAAAAA" => [ ["0xAAAAAAAA", "0x8"], ], },
"0xAAAAAAAA" => { "0x55555555" => [ ["0xFFFFFFFF", "0x8"], ],
"0xAAAAAAAA" => [ ["0x55555554", "0x3"], ], },
"self" => $hashref,
"code" => \&somesub,
"xmlparser" => $xml,
};
structure_to_xml( $var, 0 );