Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

# # This script generates the following output... # # - x - x - x - x - x - x - x - x - # $tree $VAR1 = \{ # 'banana' => { # 'value' => '1231210', # 'name' => 'date' # }, # 'apple' => { # 'time' => { # 'value' => '235959' # }, # 'date' => { # 'value' => '1231210' # } # } # }; # # # - x - x - x - x - x - x - x - x - # # How do I get the banana to to look like the apple? # # e.g. # # 'banana' => { # 'date' => { # 'value' => '1231210' # } # }, # }; # use strict; use XML::Simple; use Data::Dumper; my $text=<<EOF; <main> <apple name="date" value="1231210"/> <apple name="time" value="235959"/> <banana name="date" value="1231210"/> </main> EOF my $p1 = new XML::Simple(); my $tree; my $config = eval { $tree= $p1->XMLin($text, # ,VarAttr => 'name' # ,VarAttr => 'name', ContentKey => '-content' # ,KeyAttr => "name" # ,KeyAttr => { userdefined=>"name"} # ,KeyAttr => { userdefined=>"+name"} # ,KeyAttr => { userdefined=>"-name"} ,KeyAttr => 'name' # ,ValueAttr => {userdefined=>"name"} ) }; die("$@\n Ending") if ($@); print "\$tree " . Dumper(\$tree) . "\n"; exit 0;

Replies are listed 'Best First'.
Re: hash from xml::simple
by runrig (Abbot) on Dec 10, 2009 at 23:48 UTC
    See the ForceArray attribute in XML-Simple. See some of the other attributes also whenever you need to adjust things to get exactly the output you want. If/when it gets too hard or impossible to adjust things the way you want, see XML-Rules or XML-Twig to get things done how you want them.
      Thanks!! That worked!! Not sure why. I would have thought that it would have returned something like.
      'banana' => [ { 'value' => '1231210', 'name' => 'date' }, ]
      I already had ForceArray in my real code for a few other fields too. Huh. The others elements don't have attributes. I'll have to play with it a little more. Thanks again!

        I would have thought that it would have returned something like.

        That's exactly what it returns without KeyAttr.

        That worked!! Not sure why

        You're not surprised that KeyAttr changes

        'apple' => [ { name => 'date', value => '1231210' }, { name => 'time', value => '235959' }, ],
        into
        'apple' => [ date => { value => '1231210' }, time => { value => '235959' }, ],
        so I don't see why you're surprised that it transforms
        'banana' => [ { name => 'date', value => '1231210' }, ],
        into
        'banana' => [ date => { value => '1231210' }, ],
        For your input, I think I'd rather have this output:
        $VAR1 = { 'banana' => { 'date' => '1231210' }, 'apple' => { 'time' => '235959', 'date' => '1231210' } };
        And I can get that with XML::Rules:
        use strict; use warnings; use XML::Rules; use Data::Dumper; my @rules = ( _default => sub { "%".$_[0] => {$_[1]->{name} => $_[1]->{value}}}, main => 'pass no content', ); my $text=<<EOF; <main> <apple name="date" value="1231210"/> <apple name="time" value="235959"/> <banana name="date" value="1231210"/> </main> EOF my $p = XML::Rules->new( rules => \@rules, ); my $x = $p->parse($text); print Dumper $x;