How to parse an XML file using XML Simple in Perl

Home > Search > How-to
  by

The use of XML::Simple is discouraged. However, this article is still active for historical purposes, or if you are in an organization that has Perl scripts using XML::Simple.

Let's say you have an extremly simple XML file named cartoon.xml that consists of a single entry.

<acme>
  <name>Bugs Bunny</name>
</acme>

 

The following script will allow you to parse the values from the cartoon.xml file.

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

 

You can print the values associated with certain XML tags. For example, the following markup will print the value of the name tag. This will print Bugs Bunny to the console.

print $cartoon->{'name'};

 


Arrays

Let's say the cartoon.xml file contain an array of characters.

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

 

You can then print a particular cartoon character by specifying the array item number. 0 prints Bugs Bunny, 1 print Elmer Fudd, 2 prints Yosemite Sam. This is not ideal, because you would always need your XML to have 3 and only 3 cartoon characters.

print $cartoon->{'name'}->[0];
print $cartoon->{'name'}->[1];
print $cartoon->{'name'}->[2];

 

You could print all of the values of the name array like this. This will print Bugs Bunny Elmer Fudd Yosemite Sam. However, this will not work if there is only a single cartoon character.

print @{$cartoon->{'name'}};

 

The solution to this challenge is to use the ForceArray => 1 option.

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

 

Once the ForceArray option is used, you can then use the following to print all of the values of the array. This will work when there is only a single item in the array, or when there are two or more items in the array.

print @{$cartoon->{'name'}};

 

One caveot is that the following markup will fail to print a cartoon character once the ForceArray options is set.

print $cartoon->{'name'};

 

Instead, you would have to append the array item, like this.

print $cartoon->{'name'}->[0];

 


Multiple arrays

Let's say your cartoon.xml file wants to put the characters inside of the characters tag and the creators inside of the creator tag. 

<acme>
  <characters>
    <name>Bugs Bunny</name>
    <name>Elmer Fudd</name>
    <name>Yosemite Sam</name>
  </characters>
  <creators>
    <name>Tex Avery</name>
    <name>Chuck Jones</name>
    <name>Robert McKimson</name>
  </creators>
</acme>

 

The following will print the three characters and the three creators.

print @{$cartoon->{'characters'}->[0]->{'name'}};
print @{$cartoon->{'creators'}->[0]->{'name'}};

 


Looping through arrays

Let's say your cartoon.xml file has each character inside of a character tag.

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

 

You will need to loop through the character tag, and then display the name.

foreach my $character ( @{$cartoon->{'character'}} ) {
  print $character->{'name'}->[0];
}

 


Attributes

Let's consider this XML file that contains an attribute called description.

<acme>
  <name description="Main Character">Bugs Bunny</name>
  <name description="Support Character">Elmer Fudd</name>
  <name description="Support Character">Yosemite Sam</name>
</acme>

 

Using the ForceArray => 1 flag, the value of each attribute can be printed like this.

print $cartoon->{'name'}->[0]->{'description'};
print $cartoon->{'name'}->[1]->{'description'};
print $cartoon->{'name'}->[2]->{'description'};

 



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