Question

I'm doing something wrong when parsing XML. Somehow I has to iterate two loops, where only one should be needed. What am I doing wrong here?

First the xml data:

<fishy>
  <fish displayName          = "Scalar"
        description          = "the first fish I bought."
   />
  <fish displayName          = "crystal red"
        description          = "not really a fish."
   />
</fishy>

Then my perl code:

#!/usr/bin/perl -w
use strict;
use XML::Simple;
use Data::Dumper;

#Read configuration
my $simple = XML::Simple->new();
my $data   = $simple->XMLin('test.xml');
print Dumper($data) . "\n";


my @fishes = $data->{fish};

#This is weird.. Why do we have nested arrays?
foreach my $fish (@fishes)
{
  foreach my $innerFish (@{$fish})
  {
    print ("\n" . $innerFish->{displayName} . " is " . $innerFish->{description});
  }
    print ("\n");
}

And finally the response (which is fine)

$VAR1 = {
          'fish' => [
                    {
                      'description' => 'the first fish I bought.',
                      'displayName' => 'Scalar'
                    },
                    {
                      'description' => 'not really a fish.',
                      'displayName' => 'crystal red'
                    }
                  ]
        };


Scalar is the first fish I bought.
crystal red is not really a fish.
Was it helpful?

Solution

You create an array with one element (a reference to an array) with

my @fishes = $data->{fish};

Then you iterate over the elements of that array with

foreach my $fish (@fishes)

That's just a really weird way of doing

my $fish = $data->{fish};

Let's use that, but rename $fish to $fishes, and $innerFish to $fish.

my $fishes = $data->{fish};
for my $fish (@$fishes) {
   print($fish->{displayName}, " is ", $fish->{description}, "\n");
}

Don't forget to use the ForceArray => [qw( fish )] option to make sure the code works when you only have a single fish.

OTHER TIPS

my @fishes = @{$data->{fish}};

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top