FreeKB - Looping through keys that contain attributes using XML::Simple in Perl
Looping through keys that contain attributes using XML::Simple in Perl

Home > Search


Let's say you have an XML file that has multiple keys that have an identical name, and your objective is to parse out the character names (Bugs Bunny, Elmer Fudd, Yosemite Sam).

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

 

Let's first consider XML::Simple's default behavior.

#!/usr/bin/perl

use strict;
use warnings;
use XML::Simple;

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

print Dumper $xml;

 

Notice that only Bugs Bunny has the 'name' key. Elmer Fudd and Yosemite Sam have {}. In this condition, it is going to be very difficult to create a simple clean script to parse out Bugs Bunny, Elmer Fudd, Yosemite Sam. Let's apply two controls to clean up the data.

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

 

Adding KeyAttr => "character" will set "character" as the key, and ForceArray => 1 will store the data into arrays.

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

 

Now the data is in a much better condition, where all three characters have 'name'.

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

 

These for each loops will now print the character names.

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

foreach ( @{$xml->{support}} ) {
  foreach ( @{$_->{character}} ) {
    print "$_->{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 ae0c2 in the box below so that we can be sure you are a human.




Comments