in reply to hash from xml::simple

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.

Replies are listed 'Best First'.
Re^2: hash from xml::simple
by Anonymous Monk on Dec 11, 2009 at 00:11 UTC
    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' }, ],

        It didn't turn apple into an array with sqr brackets. It returned a hash. Exactly what I wanted. A hash all the time for one or two elements. I was surprised to get a hash because I would have expected sqr brackets from ForceArray.

        This really seems like odd behavior but I'll take it. It's exactly what I wanted.

        Take this updated code for example:

        use strict; use XML::Simple; use Data::Dumper; my $text=<<EOF; <main> <apple name="date" value="1231210"/> <apple name="time" value="235959"/> <cookies name="date" value="1231210"/> <cookies name="time" value="235959"/> <banana name="date" value="1231210"/> <butter name="date" value="1231210"/> <orange>one</orange> <milk>one</milk> <grape>one</grape> <grape>two</grape> </main> EOF my $p1 = new XML::Simple(); my $tree; my $config = eval { $tree= $p1->XMLin($text, ,ForceArray => ['banana','apple','orange'] # bingo!!! ) }; die("$@\n Ending") if ($@); print "\$tree " . Dumper(\$tree) . "\n"; exit 0;
        Unlike Milk, when I put orange into the ForceArray I get sqr brackets. Orange doesn't have an attribute but Banana does. Cookies goes right to a hash without doing anything because there are two of them.
        - x - x - x - x - x - x - x - x - $tree $VAR1 = \{ 'cookies' => { 'time' => { 'value' => '235959' }, 'date' => { 'value' => '1231210' } }, 'banana' => { 'date' => { 'value' => '1231210' } }, 'apple' => { 'time' => { 'value' => '235959' }, 'date' => { 'value' => '1231210' } }, 'orange' => [ 'one' ], 'butter' => { 'value' => '1231210', 'name' => 'date' }, 'grape' => [ 'one', 'two' ], 'milk' => 'one' }; - x - x - x - x - x - x - x - x -
        Once again. Thanks for the tip. I wouldn't have attempted that.
      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;