Bootstrap FreeKB - Perl (Scripting) - XML::Simple looping through hash keys
Perl (Scripting) - XML::Simple looping through hash keys

Updated:   |  Perl (Scripting) articles

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";
  }
}

 




Did you find this article helpful?

If so, consider buying me a coffee over at Buy Me A Coffee



Comments


Add a Comment


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