in reply to Parsing Yahoo XML Response

As the error message states there is a problem in line 28, but that is one nasty bit of obfusicated code! Lets break it up a little:

my @list; if (ref $doc->{Result} eq "HASH") { @list = $doc->{Result}; } elsif (ref $doc->{Result} eq "ARRAY") { @list = @{$doc->{Result}}; } else { @list = (); } for( @list ){

Layed out like that it looks like a lot of work! The guts is that it is supposed to generate a list and iterate over it. The complication is that the list may be generated from an array ref or a hash ref. Note though that the sigil used in the first assignment is for a scalar, yet we know there is actually a reference to a hash, and the lhs expects to see a list. Something isn't right! Changing the line to:

@list = keys %{$doc->{Result}};

may be what is required. Assuming that fixes the problem, you can re-obfusicate the code by using nested terniary operators, squeezing white space and munging the lot onto one line as a trap for the next maintainer. :)


DWIM is Perl's answer to Gödel

Replies are listed 'Best First'.
Re^2: Parsing Yahoo XML Response
by ecuguru (Monk) on Jan 06, 2007 at 10:07 UTC
    This seems to be working. Does it look better to you?
    Thanks
    my $yahoo_response = get($req_url); my $xmlsimple = XML::Simple->new(); my $yahoo_xml = $xmlsimple->XMLin($yahoo_response); foreach my $result (@{$yahoo_xml->{Result}}) { # Make sure result has a thumbnail my $title = $result->{Title}; my $url = $result->{Url}; my $click_url = $result->{ClickUrl}; # $click_url =~ s/&/&amp;/g; if (ref($result->{Cache}) eq "HASH") { ##If it has a Cache at all my $cacheUrl = $result->{Cache}->{Url}; my $cacheSize = $result->{Cache}->{Size}; $out .= "Record: $count<br>\n"; $out .= "Title: $title<br>\n"; $out .= "Url: $url<br>\n"; $out .= "CacheUrl: $cacheUrl<br>\n"; $out .= "CacheSize: $cacheSize<br>\n"; } print "out\n$out----\n"; $out = ""; $count++; }
Re^2: Parsing Yahoo XML Response
by ecuguru (Monk) on Jan 06, 2007 at 09:48 UTC
    thank you for the answer, but I wasn't able to understand all of your suggestions, despite what seems like a very well written set of suggestions. Believe me it's my ignorance to this.
    Did you mean that I should change the for loop to:
    for( ref $doc->{Result} eq "HASH"?keys %{$doc->{Result}}:ref $doc->{Re +sult}eq "ARRAY"?@{$doc->{Result}}:() ){
    ?? If so, I still get the same error. Is there another way to run the loop? Thanks!

      In that case I suggest that you try the "expanded" version of the line - that will be much easier to diagnose. If you still have trouble try generating a code sample that demonstrates the problem without requiring the extranious code. Something like this:

      #!/usr/bin/perl -w use strict; my $doc = {Result => {first => 1, second => 2} #['first', 'second'] }; my @list; if (ref $doc->{Result} eq "HASH") { @list = keys %{$doc->{Result}}; } elsif (ref $doc->{Result} eq "ARRAY") { @list = @{$doc->{Result}}; } else { @list = (); } for (@list) { print "$_\n"; }

      which prints the following (without errors or warnings):

      first second

      You might also like to use Data::Dump::Streamer to dump the contents of $doc so that you can see what is causing grief in the data.


      DWIM is Perl's answer to Gödel
        GOT IT!!
        I understand what you were saying now, MANY thanks for that secondary followup post. It really helped me understand what you meant before, and really edificated me.
        thanks again!!!