http://www.perlmonks.org?node_id=642538


in reply to XML::Simple Meets Complex Hash Structure

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:
my $xml_response_object = $xs->XMLin($response->content, forcearray => + 1);
I kept getting errors when I tried to define rootname, so I just took the default. It's not the cleanest code I've ever written, but it works.

For the Monks reading this in years to come, here's how it all turned out:

I parsed the xml response was parsed into an XML::Simple object:

my $xs = XML::Simple->new; my $xml_response_object = $xs->XMLin($response->content, forcearray => + 1);

Once parsed, it looked like this:

print Dumper($response); Response Dump: $VAR1 = { 'Preroll' => [ { 'Length' => [ '4' ], 'TrackingId' => [ 'null:414' ], 'CompanionId' => [ 'N/A' ], 'Creative' => [ 'Preroll_30sec' ], 'Impression' => [ 'TBD' ], 'Completion' => [ 'http://192.168.0.1:80/foo/ +bar' ] } ], 'Midroll' => [ { 'Length' => [ '5' ], 'TrackingId' => [ 'null:416' ], 'CompanionId' => [ 'N/A' ], 'Creative' => [ 'Midroll_45sec_2' ], 'Impression' => [ 'TBD' ], 'Completion' => [ 'http://192.168.0.1:80/foo/ +bar' ] }, { 'Length' => [ '5' ], 'TrackingId' => [ 'null:415' ], 'CompanionId' => [ 'N/A' ], 'Creative' => [ 'Midroll_45sec_1' ], 'Impression' => [ 'TBD' ], 'Completion' => [ 'http://192.168.0.1:80/foo/ +bar' ] }, { 'Length' => [ '5' ], 'TrackingId' => [ 'null:417' ], 'CompanionId' => [ 'N/A' ], 'Creative' => [ 'Midroll_45sec_3' ], 'Impression' => [ 'TBD' ], 'Completion' => [ 'http://192.168.0.1:80/foo/ +bar' ] } ], 'Postroll' => [ { 'Length' => [ '6' ], 'TrackingId' => [ 'null:418' ], 'CompanionId' => [ 'N/A' ], 'Creative' => [ 'Postroll_60sec' ], 'Impression' => [ 'TBD' ], 'Completion' => [ 'http://192.168.0.1:80/foo +/bar' ] } ] };

I was able to walk the entire object with this code:

foreach my $asset_type ( keys %{$response} ) { $logger->debug("Starting asset_type $asset_type"); my $i = 0; while ($response->{$asset_type}->[$i]) { $logger->debug("\t$asset_type $i:"); foreach my $param ( keys %{($response->{$asset_type}->[$i])}) { # + each $i is a hash ref $logger->debug("\t\t$param = $response->{$asset_type}->[$i]->{$p +aram}->[0]"); } $i++; } }
And I was able to access the lowest-level data directly using:

$response->{$asset_type}->[$i]->{Creative}->[0]

The logging is handled by Log::Log4perl, which is the logging package I've been looking for for years. The HTTP request is handled by LWP::UserAgent, HTTP::Request, HTTP::Response, and URI::Heuristic, and debugging was vastly aided by Data::Dumper.

-Logan
"What do I want? I'm an American. I want more."