ashutosh raina
ashutosh raina

Reputation: 9314

How to read data from a hash in Perl?

I have the following XML file:

<?xml version='1.0'?>
<preferences>
    <font role="console">
        <fname>Courier</fname>
        <size>9</size>
    </font>
    <font role="default">
        <fname>Times New Roman</fname>
        <size>14</size>
    </font>
    <font role="titles">
        <fname>Helvetica</fname>
        <size>10</size>
    </font>
</preferences>

I managed to read it and dump it out. Now I am supposed to read all the key value pairs.

Here is the script:

#!/usr/bin/perl

use warnings;
use strict;
# use module
use XML::Simple;
use Data::Dumper;

my $data = XMLin('test.xml');

# print Dumper(%data);


while ( my ($key, $value) = each(%$data) ) {
    print "$key => $value\n";
}

Nothing prints inside the loop... What could be the problem? I am new to this and wrote my Hello World script and this all in the same day, so I will take any advice on the code.

This works just fine:

my $data = XMLin('test.xml');
print Dumper($data);

And it gives me:

$VAR1 = {
          'font' => [
                    {
                      'fname' => 'Courier',
                      'role' => 'console',
                      'size' => '9'
                    },
                    {
                      'fname' => 'Times New Roman',
                      'role' => 'default',
                      'size' => '14'
                    },
                    {
                      'fname' => 'Helvetica',
                      'role' => 'titles',
                      'size' => '10'
                    }
                  ]
        };

I am guessing that inside the while loop I need to loop through each of the arrays. Am I right?

Upvotes: 2

Views: 3752

Answers (2)

sergio
sergio

Reputation: 69027

Try with:

 while ( my ($key, $value) = each(%$data) ) {      
   ....

Upvotes: 2

TLP
TLP

Reputation: 67900

use strict;

Is your friend. It would have told you:

Global symbol "%data" requires explicit package name

What you want is %$data

In other words: $data and %data counts as two different variables.

Update:

As you changed the whole question, my answer makes little sense now.. As does your question. You have printed it. What else do you need?

If you wanted to print that structure, you'd need something like (untested):

for my $key1 (keys %$data) {
    for my $array_value (@{ $data->{$key1} }) {
        for my $key2 (keys %$array_value) {
            print "$key2 => $array_value->{$key2}\n";
        }
    }
}

If you wanted to access a value directly:

print $data->{font}[0]{'fname'}

You'll need to experiment to get what you need. In the Data::Dumper output, you can easily see which values are hashes and which are arrays:

$VAR1 = {   # The curly bracket denotes a beginning hash 
          'font' => [     # Square bracket = array begins
                    {     # The first array element is a hash 
                      'fname' => 'Courier',   # Inside the hash
                      'role' => 'console',
                      'size' => '9'
                    },    # Hash ends
                    {     # Next array value, new hash begins
                      'fname' => 'Times New Roman',
                      'role' => 'default',
                      'size' => '14'
                    },
                    {
                      'fname' => 'Helvetica',
                      'role' => 'titles',
                      'size' => '10'
                    }
                  ]     # Array ends
        }; # Hash ends

Upvotes: 8

Related Questions