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

What is the best way to parse XML responses? I am trying to use XML::Bare. Here is my code:
my $ob = new XML::Bare( text => "$page" ); my $root = $ob->parse(); #Where $page contains something like this: <?xml version="1.0" encoding="ISO-8859-1" ?> <PayoneerResponse> <Echo> <Status>000</Status> <Description>Echo Ok - All systems are up.</Description> </Echo> </PayoneerResponse>
$root appears to be blank, so I don't know why that is happening. Payoneer responds with so many different things, not the same format everytime, so I need to use something basic.
They never put an ending '</xml>' and when I add it, I get a parsing error.

What would You use to parse the response from them?

thank you,
Richard

Replies are listed 'Best First'.
Re: parsing various xml responses
by ikegami (Patriarch) on Dec 13, 2009 at 22:34 UTC

    $root appears to be blank

    No, it returns what it should

    use XML::Bare; use Data::Dumper; my $page = '<?xml version="1.0" encoding="ISO-8859-1" ?> <PayoneerResponse> <Echo> <Status>000</Status> <Description>Echo Ok - All systems are up.</Description> </Echo> </PayoneerResponse>'; my $ob = new XML::Bare( text => $page ); my $root = $ob->parse(); local $Data::Dumper::Indent = 1; print(Dumper($root));
    $VAR1 = { '_z' => 0, '_i' => -26338708, 'PayoneerResponse' => { '_z' => 178, '_i' => 47, 'value' => ' ', '_pos' => 1, 'Echo' => { '_z' => 158, '_i' => 66, 'Status' => { '_z' => 91, '_i' => 73, 'value' => '000', '_pos' => 3 }, 'value' => ' ', '_pos' => 2, 'Description' => { '_z' => 149, '_i' => 95, 'value' => 'Echo Ok - All systems are up.', '_pos' => 4 } } }, 'value' => ' ', '_pos' => 0 };

    They never put an ending '</xml>'

    Nor should they. The root element is named PayoneerResponse, not xml.

    What would You use to parse the response from them?

    Of the parsers I've tried, XML::LibXML is by far the fastest, it has a good interface, and actually handles namespaces correctly. It is my XML parser of choice.

Re: parsing various xml responses
by keszler (Priest) on Dec 13, 2009 at 22:37 UTC
    It works fine for me like this:

    Are you using the {value} key?

      Yes, when I exit out with output to test it I print to html this:
      print qq~ \$root->{xml}->{PayoneerResponse}->{Echo}->{Status}->{value}='~, $root +->{xml}->{PayoneerResponse}->{Echo}->{Status}->{value}, qq~'; \$root->{PayoneerResponse}->{Echo}->{Status}->{value}='~, $root->{Payo +neerResponse}->{Echo}->{Status}->{value}, qq~'; \$root->{Status}->{value}='~, $root->{Status}->{value}, qq~'; ~;
      Which prints this to the HTML output:
      $root->{xml}->{PayoneerResponse}->{Echo}->{Status}->{value}='';
      $root->{PayoneerResponse}->{Echo}->{Status}->{value}='';
      $root->{Status}->{value}='';

      So I have tried a lot of different ways and cannot get it to work.

      Can you see what I'm doing wrong in the $root variables or anything?

      Thanks
      Richard
        I even tried taking out the other -> in the code:
        print qq~ \$root->{PayoneerResponse}{Echo}{Status}{value}='~, $root->{PayoneerRe +sponse}{Echo}{Status}{value} ,qq~'; \$root->{Status}{value}='~, $root->{Status}{value}, qq~'; ~;
        which prints this result:
        $root->{PayoneerResponse}{Echo}{Status}{value}='';
        $root->{Status}{value}='';

        Still does not work.

        Richard
        I got it to work... I had an error up top.

        Thank you much!

        Richard
Re: parsing various xml responses
by pajout (Curate) on Dec 14, 2009 at 12:23 UTC
    use XML::Trivial; use strict; use warnings; my $obj = XML::Trivial::parse('<?xml version="1.0" encoding="ISO-8859- +1" ?> <PayoneerResponse> <Echo> <Status>000</Status> <Description>Echo Ok - All systems are up.</Description> </Echo> </PayoneerResponse>'); print $$obj{PayoneerResponse}{Echo}{Status}->ts;
Re: parsing various xml responses
by Anonymous Monk on Dec 17, 2009 at 03:32 UTC
    Ok, it is not working again, this is in the same routine, the first one works, but now this one does not work... Here is the code:
    $_xmlCode = q~<?xml version="1.0" encoding="UTF-8"?><PayoneerToken><To +ken>https://sandbox.payoneer.com/partners/lp.aspx?token=akn2w3knsnk32 +3lnknasdin4falkngnaskjncik32l12</Token></PayoneerToken> ~; $ob = new XML::Bare( text => "$_xmlCode" ); $root = $ob->parse(); $_redirectUrl = $root->{PayoneerToken}{Token}{Value}; # Print to browser to see if it is working... print "Content-type: text/html\n\n"; print qq~ \$_redirectUrl = '$_redirectUrl';<br> <br> <b>\$_xmlCode='$_xmlCode'</b>;<br>~;
    And it does not work, it prints this in the browser:
    ## Browser output not perl code: $_redirectUrl = ''; $_xmlCode='<?xml version="1.0" encoding="UTF-8"?><PayoneerToken><Token +>https://sandbox.payoneer.com/partners/lp.aspx?token=akn2w3knsnk323ln +knasdin4falkngnaskjncik32l12</Token></PayoneerToken>';
    Any idea now, why that would not work? I've tried changing the variables names and everything.

    I installed XML::Trivial as pajout suggested in his thread. I used the cpan module to install it with all the dependencies but I had to force it to get it to install, and it returned make success, however, when just calling the use on it, I get errors on the server, so I am not going to even try using that one.

    I would really appreciate any advice on what you think the problem could be now.

    Thank you again.
    Richard
      When in doubt, use Data::Dumper to dump the tree. There's no key named Value, but there is one named value.
        Ok, I did the dump, and here is the result:
        Dump of $root2 { PayoneerToken => { Token => {} }, _i => -416395696, _pos => 0, _z => + 0, value => "<?xml version=\"1.0\" encoding=\"UTF-8\"?><PayoneerToke +n><Token>https://sandbox.payoneer.com/partners/lp.aspx?token=akn2w3kn +snk323lnknasdin4falkngnaskjncik32l12</Token></PayoneerToken>", }

        Any clues as to why it is broken?

        thanks again,
        Richard
      Just wanted to say, I tried it first with: $root->{PayoneerToken}{Token}{value};
      and it did not work so I tried it the way I show it above:
      $root->{PayoneerToken}{Token}{Value}; neither one are working for me.

      Thanks,
      Richard