Looping through keys using XML::Simple in Perl

Home > Search
  by

Let's say you have an XML file that has multiple keys that have an identical name. In this example, below the <acme> key there are multiple <character> keys. A foreach loop can be used to loop through each <character> key.

 


Method 1 (hash)

Near the beginning of your Perl script, use the XML::Simple module and use XMLin to parse the XML file.

#!/usr/bin/perl
use XML::Simple;
$xml = XMLin("cartoon.xml");

 

We can then loop through the <character> keys, and then print the value of the <name> key. This will print Bugs Bunny, Elmer Fudd, and Yosemite Sam to the console.

Notice in this example the % character is used, which signifies a hash. 

foreach $name ( keys %{$xml->{'character'}} ) {
  print $name;
}

 


Method 2 (array)

Near the beginning of your Perl script, use the XML::Simple module, use XMLin with ForceArray => 1 to parse the XML file.

#!/usr/bin/perl
use XML::Simple;
$xml = XMLin("cartoon.xml", ForceArray => 1 );

 

We can then loop through the <character> keys, and then print the value of the <name> key. This will print Bugs Bunny, Elmer Fudd, and Yosemite Sam to the console.

Notice in this example the @ character is used, which signifies an array. 

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

 


Nested arrays

Some XML files may be arranged in such a way that you must use nested loops to capture the data you want. For example, consider the following XML file. 

<acme>
  <character>
    <main>
      <name>Bugs Bunny</name>
    </main>
  </character>

  <character>
    <main>
      <name>Elmer Fudd</name>
    </main>
  </character>

  <character>
    <main>
      <name>Yosemite Sam</name>
      <name>Tweety Bird</name>
    </main>
  </character>
</acme>


If you want to print each character, you would first need to loop through the <characters> tags to load everything below characters into memory. You would next need to loop through the <main> tags to get each character.

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

 

If you are getting "Not an Array reference", you can debug this by checking to see if each collection of tags returns a HASH memory address. In this example, we are checking to see if the <main> tags return a hash.

foreach $character ( @{$xml->{'character'}} ) {
  print @{$character->{'main'}};
}

 

If they do, the text HASH followed by the memory address should be returned for each <main> tag.

HASH(0x123234234)
HASH(0x123234344)
HASH(0x124523423)

 

If your XML tags have attributes, such as <main id="hello" class="world">, the attributes may cause "Not an Array reference". If possible, the attributes can be removed from the tags. 



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 in the box below so that we can be sure you are a human.




Comments