Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

Looping through nested repeated elements using XML::Simple

by ranjan_jajodia (Monk)
on Dec 13, 2006 at 06:43 UTC ( #589498=perlquestion: print w/replies, xml ) Need Help??

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

I am trying to loop through nested repeated elements in my config file but I am unable to find the number of nested elements:
Sample XML File:
<opt> <person firstname="Joe" lastname="Smith"> <email></email> <email></email> </person> <person firstname="Bob" lastname="Smith"> <email></email> </person> </opt>

Perl Code:
use XML::Simple; use strict; use Data::Dumper; my $config = XMLin("testFile.xml",forcearray => ['person','email']); my @persons = $config->{person}; print "Size:".@persons;
On running I always get the size as 1. I think the way I am trying to get the size is wrong because in order to get the person blocks I need to do $config->{person}->[0] etc. instead of $config->{person}[0]. I admit I have not used hashes earlier but I did try keys function on $config->{person} which gives "Type of arg 1 to keys must be hash (not hash element)" error. Could anyone please tell me the right way to loop through the elements?

Replies are listed 'Best First'.
Re: Looping through nested repeated elements using XML::Simple
by ikegami (Patriarch) on Dec 13, 2006 at 06:50 UTC

    $config->{person} returns a reference to an array, not an array.

    my $persons = $config->{person}; print "Size:".@$persons;

    Hashes values can't be arrays, only scalars. References are scalars, so references to arrays are valid hash values.

      Thanks ikegami for the explanation. I am off to exploring more on the same.
Re: Looping through nested repeated elements using XML::Simple
by pemungkah (Priest) on Dec 13, 2006 at 07:02 UTC
    Well, let's do what we should do when we have a data structure we don't understand: look at it in the debugger.
    $ perl -d Loading DB routines from version 1.28 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::( my $config = XMLin("testFile.xml",forc +earray => ['person','email']); + DB<1> l 5==> my $config = XMLin("testFile.xml",forcearray => ['person','ema +il']); 6: my @persons = $config->{person}; 7: print "Size:".@persons; DB<1> c 6 # run continuously to line 6 main::( my @persons = $config->{person}; DB<2> x $config 0 HASH(0x1988e88) 'person' => ARRAY(0x19acb00) 0 HASH(0x1988f30) 'email' => ARRAY(0x19acba8) 0 '' 1 '' 'firstname' => 'Joe' 'lastname' => 'Smith' 1 HASH(0x198a0cc) 'email' => ARRAY(0x19acab8) 0 '' 'firstname' => 'Bob' 'lastname' => 'Smith' DB<3> q $
    So we can see that the value of $config->{person} is actually a reference to an array, not an array itself. You'll have to dereference it to get an actual array. Try @{ $config->{person} }. The elements in the array created by this expression will be the two references to the hashes containing references to arrays containing the email values.
      Thanks pemungkah for the explaining the way to solve this kind of problem. I was using DataDumper to see the contents but this way I can do more things while debugging.
        You're very welcome. One other thing: you can play around with expressions in the debugger as well. For instance, if you wanted to see what @{ $config->{person} } would give you, you could just enter x @{ $config->{person} } at the debugger prompt, and the debugger would happily dump it out for you.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://589498]
Approved by ikegami
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2023-12-11 22:16 GMT
Find Nodes?
    Voting Booth?
    What's your preferred 'use VERSION' for new CPAN modules in 2023?

    Results (41 votes). Check out past polls.