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

I can successfully make a SOAP request and dump the response:
my $soap = SOAP::Lite -> proxy($url); my $res = $soap->$method(@data); use Data::Dumper; print Dumper($res)
But, after spending hours trying to decipher the documentation of SOAP::Lite (and ::SOM) I cannot for the life of me figure out how to access (as variables) some of the sub elements of the data that is returned. I'd like to code something similar to the following pseudo code:
Foreach campaign in campaigns { print $campaign{Name}; print $campaign{Cost}; print $campaign{Sessions}{Number}; print $campaign{Sessions}{TotalVisits}; }
out of the following sample data (in XML for brevity)
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/env +elope/"> <SOAP-ENV:Body> <APIResponse> <ClickFraudReport> <Name>Click Fraud Report</Name> <TimeRange>Thursday, November 23, 2006 - Wednesday, November 2 +9, 2006</TimeRange> <Campaigns> <Campaign> <Name>Google 140</Name> <Cost>$330.14</Cost> <LandingPage>/?source=29938</LandingPage> <Keywords>probability, stasticial analysis</Keywords> <Headline>Special Headline</Headline> <Criterion>http://www.mywebsite.com?source=29938</Criterio +n> <Sessions> <Number>230</Number> <TotalVisits>7733</TotalVisits> <Changed>0</Changed> <OldNumber>267</OldNumber> <OldTotalVisits>10249</OldTotalVisits> </Sessions> </Campaign> <Campaign> <Name>Google 28</Name> <Cost>$566.02</Cost> <LandingPage>/?source=29033</LandingPage> <Keywords>caution, long tail</Keywords> <Headline>Even Better Headline</Headline> <Criterion>http://www.mywebsite.com?source=29033</Criterio +n> <Sessions> <Number>837</Number> <TotalVisits>4599</TotalVisits> <Changed>0</Changed> <OldNumber>112</OldNumber> <OldTotalVisits>10883</OldTotalVisits> </Sessions> </Campaign> </Campaigns> </ClickFraudReport> </APIResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
Thanks for any help.

Replies are listed 'Best First'.
Re: How to access elements that SOAP::Lite Returns
by rhesa (Vicar) on Nov 30, 2006 at 19:32 UTC
    have you tried my $report = $res->result;? That should give you the unwrapped data structure, which should look roughly like:
    $VAR1 = { 'ClickFraudReport' => { 'Name' => 'Click Fraud Report', 'TimeRange' => 'Thursday, November 23, 2006 - Wednesday, Novem +ber 29, 2006'. 'Campaigns' => [ { 'Name' => 'Google 140', 'Cost' => '$330.14', # etc }, { # etc }, ], }, };
    That means you can loop over the campaigns by doing:
    my $report = $res->result; foreach my $campaign ( @{ $report->{ClickFraudReport}{Campaigns} } ) { print $campaign->{Name}; print $campaign->{Cost}; }

    See the SOAP::Lite docs for more info. Specifically read the section on the call() method.

      Thanks, That was really helpful. The choices SOAP::Lite makes for the data structure seem entirely random (Hash or Array?!!) and unpredictable to me, so I just chose to get XML and parse it this way. It works for now. I'm open to more elegant solutions, but it works.
      foreach my $campaign (@{$output->{'SOAP-ENV:Body'}->{APIResponse}->{ClickFraudReport}-> +{Campaigns}->{Campaign}} ) { print "\n\n"; print " Campaign: $campaign->{Name}\n"; print " Cost: $campaign->{Cost}\n"; ...
Re: How to access elements that SOAP::Lite Returns
by meetraz (Hermit) on Nov 30, 2006 at 19:21 UTC
    It sounds like your soap call is returning this data as a single raw XML string. You probably need to parse the XML using something like XML::Simple or XML::Parser.

Re: How to access elements that SOAP::Lite Returns
by Herkum (Parson) on Nov 30, 2006 at 19:24 UTC
    As I recall XML::SOAP did come with its own parser. The result was that it returned the XML back as a giant hash. I don't remember off hand what was required to do it but it is possible and should be easy.
Re: How to access elements that SOAP::Lite Returns
by meetraz (Hermit) on Nov 30, 2006 at 19:21 UTC