FreeKB - XML Simple in Perl - foreach keys loop - hash
XML Simple in Perl - foreach keys loop - hash

Home > Search


When looping through keys using XML::Simple, there are two main approaches.

  • Loop through keys as hash
  • Loop through keys as array

This article deals with looping through keys as a hash. Let's consider this XML.

<acme>
  <character>
    <name>Bugs Bunny</name>
  </character>
  <character>
    <name>Elmer Fudd</name>
  </character>
  <character>
    <name>Yosemite Sam</name>
  </character>
</acme>

 

Before looping through an XML file as a hash, it usually makes sense to view the structure of the XML file using Dumper.

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

my $xml = XMLin("cartoon.xml");

print Dumper $xml;

 

In this example, Dumper will produce the following output.

$VAR1 = {
          'character' => {
                           'Bugs Bunny' => {},
                           'Elmer Fudd' => {},
                           'Yosemite Sam' => {}
                         }
         };

 

This will print Bugs Bunny, Elmer Fudd, and Yosemite Sam.

foreach ( keys %{$xml->{character}} ) {
  print "$_\n";
}

 


Loop through array

Add ForceArray => 1 to parse the XML file as an array instead of a hash.

my $xml = XMLin("cartoon.xml", ForceArray => 1 );

 

In this example, Dumper will print the following. The main takeaway here is that Bugs Bunny, Elmer Fudd, and Yosemite Sam are surrounded by [ ], which means these values are in an array.

$VAR1 = {
          'character' => [
                         'Bugs Bunny',
                         'Elmer Fudd',
                         'Yosemite Sam'
                         ]
         };

 

This will print Bugs Bunny, Elmer Fudd, and Yosemite Sam to the console.

foreach ( @{$xml->{character}} ) {
  print "$_\n";
}

 

 


3 layers

Let's consider the same XML file where the values are 3 "layers" deep.

<acme>
   <character>
     <name role="main">Bugs Bunny</name>
     <name role="support">Elmer Fudd</name>
     <name role="support">Yosemite Sam</name>
   </character>
</acme>

 

Dumper will produce the following. The big takeaway here is that there are two arrays, "character" and "name". 

$VAR1 = {
          'character' => [
                           {
                            'name' => [
                                      'Bugs Bunny',
                                      'Elmer Fudd',
                                      'Yosemite Sam'
                                      ]
                           }
                         ]
         };

 

In this situation, you would loop through the first array (character) and then print the second array (name).

foreach ( @{$xml->{character}} ) {
  print @{$_->{name}};
}

 


4 layers

Let's consider the same XML file where the values are 3 "layers" deep.

<acme>
   <character>
     <role>
       <name>Bugs Bunny</name>
       <name>Elmer Fudd</name>
       <name>Yosemite Sam</name>
     </role>
   </character>
</acme>

 

Dumper will show there are 3 arrays, "character", "role", and "name". In this situation, you first need to loop through the "character" array, then loop through the "role" array, and then you can print the values in the "name" array.

foreach my $character ( @{$xml->{character}} ) {
  foreach my $main ( @{$character->{main}} ) {
    print "@{$main->{name}}\n";
  }
}

 



Add a Comment




We will never share your name or email with anyone. Enter your email if you would like to be notified when we respond to your comment.




Please enter 91d65 in the box below so that we can be sure you are a human.




Comments