Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

xml simple not a hash reference

by Noverast (Initiate)
on Dec 28, 2010 at 10:25 UTC ( #879412=perlquestion: print w/replies, xml ) Need Help??

Noverast has asked for the wisdom of the Perl Monks concerning the following question:

I can loop through each roomtype but if a roomtype has more that one mealtype I get this error: The ForceArray option is enabled. Please Help!

gives me this error message / faulty output:

Not a HASH reference

This is the dump from the XML that is begin returned to me:

$VAR1 = { 'success' => 'true', 'data' => { 'bb' => { 'roomtypes' => { 'roomtype' => [ { 'rtimage' = +> '10002-2.jpg', 'ratescheme +' => '1', 'rtid' => ' +2', 'roomsfree' + => '2', 'childpolic +y' => { + 'general' => '2 - 12 years stay', + 'allowchild2' => 'Y', + 'allowchild1' => 'Y' + }, 'mealtypes' + => { + 'mealtype' => [ + { + 'defaultmealtype' => 'true', + 'rates' => { + 'pax3' => '1180.00', + 'pax2' => '930.00', + 'pax4' => '1405.00', + 'pax1' => '550.00' + }, + 'mealtypedesc' => 'Bed & Breakfast', + 'rateid' => '6' + }, + { + 'rates' => { + 'pax3' => '850.00', + 'pax2' => '700.00', + 'pax4' => '975.00', + 'pax1' => '450.00' + }, + 'mealtypedesc' => 'Self-catering', + 'rateid' => '7' + } + ] + }, 'maxoccupan +cy' => '6', 'minlos' => + '0', }, { 'ratescheme +' => '1', 'rtid' => ' +1', 'roomsfree' + => '5', 'descriptio +n' => 'Double bed', 'childpolic +y' => { + 'general' => '2 - 12 years stay', + 'allowchild2' => 'Y', + 'allowchild1' => 'Y' + }, 'mealtypes' + => { + 'mealtype' => { + 'defaultmealtype' => 'true', + 'rates' => { + 'pax2' => '800.00', + 'pax1' => '500.00' + }, + 'mealtypedesc' => 'B&B', + 'rateid' => '5' + } + }, 'maxoccupan +cy' => '2', 'minlos' => + '0', } ] }, }, 'nights' => '1', 'enddate' => '2011-01-24', 'startdate' => '2011-01-23' } };

Replies are listed 'Best First'.
Re: xml simple not a hash reference
by Anonyrnous Monk (Hermit) on Dec 28, 2010 at 11:29 UTC

    I think it would help if you could show the code that produces the error. The data alone (what you've shown) doesn't produce any error messages.

    diagnostics says

    $ echo "Not a HASH reference" | splain Not a HASH reference (#1) (F) Perl was trying to evaluate a reference to a hash value, but f +ound a reference to something else instead. You can use the ref() functi +on to find out what kind of ref it really was. See perlref.
Re: xml simple not a hash reference
by roboticus (Chancellor) on Dec 28, 2010 at 13:17 UTC

    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.

      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...)

Re: xml simple not a hash reference
by Jenda (Abbot) on Dec 29, 2010 at 14:06 UTC

    Looks to me like it's time to start tweaking the datastructure as it's being built to get something both consistent and easier to handle. See Simpler than XML::Simple.

    Jenda
    Enoch was right!
    Enjoy the last years of Rome.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://879412]
Approved by ELISHEVA
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (3)
As of 2023-06-01 13:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?