in reply to xml simple not a hash reference

Noverast:

If you look a bit more closely at your data, you'll notice that data/bb/roomtypes/roomtype is an arrayref holding a hashref. So I'd suspect that your code is trying to do something like:

$hrXml->{data}{bb}{roomtypes}{roomtype}{$aKey};

instead of:

$hrXml->{data}{bb}{roomtypes}{roomtype}[$anIndex]{$aKey};

Note: I've seen a couple other array references in your data too, but I only mentioned the first one. So your error may be coming from one of the others. Also, if you're going to post a chunk of data like that, you should indent your data using less whitespace to make it a bit more readable.

I've heard about XML::Simple having an option (ForceArray) to force certain keys to always use an array reference. I believe (having never used it) that it'll use an array reference if the key has multiple sub-values and a hash reference if the key has only one. That can make your code a little tricky. But if you use ForceArray for the keys that may change on you, then your code can be simplified. (Anyway, that's what I gather from several posts. I'm sure someone will correct me if I misunderstood.)

...roboticus

When your only tool is a hammer, all problems look like your thumb.

Replies are listed 'Best First'.
Re^2: xml simple not a hash reference
by Noverast (Initiate) on Dec 28, 2010 at 13:50 UTC

    Thank you for the responses. This is my code:

    my $results = $res->content; $xml = new XML::Simple (KeyAttr => [],suppressempty => 1,ForceArray => + ['roomtype']); $data = $xml->XMLin("$results"); foreach $e (@{$data->{data}->{bb}->{roomtypes}->{roomtype}}){ $roomtypename=$e->{roomtypename}; $rateid=$e->{mealtypes}->{mealtype}->{rateid}; }

    I only receive the error when trying to get the value of rateid for the mealtype, if it is more than one, and I don't know how to loop through the mealtypes

      I don't know how to loop through the mealtypes

      The same way you're looping through the roomtypes:

      for my $mealtype ( @{$e->{mealtypes}->{mealtype}} ) { $rateid = $mealtype->{rateid}; }

      but don't forget to apply ForceArray to mealtype, too; or check with ref if $e->{mealtypes}->{mealtype} is an array reference, and only loop in that case (otherwise, you'd get an error if there's only one mealtype entry, in which case XML::Simple (without ForceArray in effect) would not create an extra array...)

        It is sorted out now! Thank you very much for all the help

        Thanks, I am almost there. I am using the following code:

        my $type = ref( $e->{mealplans}->{mealplan} ); if ($type eq "ARRAY") { $mealplans=$e->{mealtypes}->{mealtype}; for my $mealtype ( @{$e->{mealtypes}->{mealtype}} ) { $rateid = $mealtype->{rateid}; print "$mealtype"; } }

        It prints out: HASH(0x27acfbc)HASH(0x27acfcc) How do I get the Array readable?

        This is what I am getting

        $VAR1 = { 'defaultmealplan' => 'true', 'rates' => { 'pax3' => '1180.00 +', 'pax2' => '930.00', 'pax4' => '1405.00', 'pax1' => '550.00' }, 'me +alplandesc' => 'Bed & Breakfast', 'rateid' => '6' }; $VAR1 = { 'rates' => { 'pax3' => '850.00', 'pax2' => '700.00', 'pax4' +=> '975.00', 'pax1' => '450.00' }, 'mealplandesc' => 'Self-catering', + 'rateid' => '7' };

        Thanks, I am almost there. I used the following code:

        my $type = ref( $e->{mealtypes}->{mealtype} ); if ($type eq "ARRAY") { for my $mealtype ( @{$e->{mealtypes}->{mealtype}} ) { $rateid = $mealtype->{rateid}; print "$mealtype"; } }

        However now I getting HASH(0x279d04c)HASH(0x279d05c). How do get the array in a readable state?