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

Greetings Monks.
I'm trying to parse a chunk of XML code and the problem has become significantly more complex than I'm used to.
I am requesting an xml page that describes one or more ads. There can be any number of ads returned, and any number of ads of a specific type. I am OK when there is only one ad of a given type, but multiple ads of a given type is problematic. Here is an example of the xml returned from a request for one Preroll, 3 Midroll, and one Postroll:

What I need to do is walk through the object so I can compare the values for the end parameters (Length, Creative, etc) for each ad with the expected values. The problems are:

I won't know in advance what order the xml elements will be in. It may be Preroll, Midroll, Postroll, or it may be Midroll, Postroll, Preroll. There is no way of knowing in advance.

If there is only one ad returned for a specific ad type, '*roll' will be a hash reference. If there are multiple ads returned, '*roll' will be a reference to an anonymous array of hashes. It is possible to know in advance which ad type will have multiple ads returned and how many there should be.

What I need is an algorithm that will walk the master hash reference and be smart enough to recognize whether it's encountered a simple hash or an array of hashes and act accordingly.
I've tried this:

At that point the program dies with the error "Bad index while coercing array into hash at OO_HttpInterfaceTest.pm line 779."
Line 779 in this case is:
$logger->debug("\t$asset_type asset_param $asset_param exists: ($asset_param) = $response->{$asset_type}->{$asset_param}");. If I remove the logging statement, the code chokes on line 780 with the same error, which leads me to suspect that the actual error is with the statement "$response->{$asset_type}->{$asset_param}"

The break is happening after the Midroll section is evaluated. The value for 'Completion' is displayed at which point the loop should exit. What seems to be happening is the code tests if $response->{$asset_type}->{$asset_param} exists, finds that it doesn't, and exits rather than going to the else condition. I have no idea why it only does this when transitioning from walking the anonymous array back to a normal hash.

I've been on this for most of the day. Please help! And if there's some vastly easier/less complex way to do this, I'm all ears.

Thanks to all who weighed in with help. This was my first time working with XML and the mass of available perl libraries of both encouraging and daunting. In the end I used XML::Simple and defined forcearray: