Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

SOAP::Deserializer problem

by axelrose (Scribe)
on Jul 27, 2007 at 13:07 UTC ( #629091=perlquestion: print w/replies, xml ) Need Help??

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

Hello all, I have difficulties to process a certain SOAP reply.
#!/usr/bin/perl use warnings; use strict; use SOAP::Lite; my $xml = <<'eof'; <?xml version="1.0"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/env +elope/"> <SOAP-ENV:Header/> <SOAP-ENV:Body> <command id="20070727.103749.843"> <message id="20070727.103749.843"> <commands> <command/> </commands> <time time="27.07.2007-10:37:49 +0200"/> </message> </command> </SOAP-ENV:Body> </SOAP-ENV:Envelope> eof my $som = SOAP::Deserializer->deserialize($xml); for my $item ($som->dataof("/Envelope/Body/command/*")) { print "got 'command' item '", $item->name(), "'\n"; my $i = 1; for my $subitem ($som->dataof("/Envelope/Body/command/[$i]/*")) { print "got 'command' subitem $i '", $subitem->name(), "'\n"; my $j = 1; for my $subsubitem ($som->dataof("/Envelope/Body/command/[$i]/[$j] +/*")) { print "got 'command' subsubitem $i:$j '", $subsubitem->name(), " +'\n"; $j++; } $i++; } }
If I run this I'll get:
Use of uninitialized value in print at /Users/ar/work/soap/clients/des +erialize-test.pl line 30. Use of uninitialized value in print at /Users/ar/work/soap/clients/des +erialize-test.pl line 33. Use of uninitialized value in print at /Users/ar/work/soap/clients/des +erialize-test.pl line 30. got 'command' item 'message' got 'command' subitem 1 '' got 'command' subsubitem 1:1 '' got 'command' subitem 2 ''
If I change the id-attribute to different values or leave it out completely all runs smooth:
got 'command' item 'message' got 'command' subitem 1 'commands' got 'command' subsubitem 1:1 'command' got 'command' subitem 2 'time'
Is this on purpose? How could a access the raw XML SOAP body, avoiding to use the SOAP::Deserializer? Thanks for your time, Axel.

Replies are listed 'Best First'.
Re: SOAP::Deserializer problem
by radiantmatrix (Parson) on Jul 27, 2007 at 14:49 UTC

    The 'use of uninitialized value' in your output are warnings: the "command" tagset in your source XML is empty, so the Deserializer properly sets the values to undef. When you try to print an undef value, and you have warnings enabled, you get that message.

    Try this pattern for your print statements:

    print "got 'command' subitem $i '", (defined $subitem->name() ? $subitem->name() : '<<undefined>>') , "'\n";

    The second line of that basically says "if the value is defined, then pass it to print, otherwise pass back the string '<<undefined>>'". The result is that your output would say something like:

    got 'command' subitem 1 '<<undefined>>'
    <radiant.matrix>
    Ramblings and references
    The Code that can be seen is not the true Code
    I haven't found a problem yet that can't be solved by a well-placed trebuchet
      Ok. This get's me a step forward. The output is now
      got 'command' item 'message' got 'command' subitem 1 '<<undefined>>' got 'command' subsubitem 1:1 '<<undefined>>' got 'command' subitem 2 '<<undefined>>'
      Nonetheless I still don't have the name of the XML nodes. What I eventually need is the value of such nodes. How could I access them?? Axel.

        I'm not entirely familiar with SOAP::Deserializer; I've generally used XML::Simple family of parsers, and I've not had such problems with them. Sorry I can't be of more help than that.

        <radiant.matrix>
        Ramblings and references
        The Code that can be seen is not the true Code
        I haven't found a problem yet that can't be solved by a well-placed trebuchet
Re: SOAP::Deserializer problem
by rahed (Scribe) on Jul 28, 2007 at 18:01 UTC
    You process a soap response so I suppose you have a soap request object with data in $request.
    You want to initialize the request as
    $response = $soap->myrequest($request);

    Then after applying a valueof method on return object you can access your values:

    $value1 = $response->valueof('//Envelope/Body/command');
    $value2 = $response->valueof('//Envelope/Body/command/message');

    or you can check if the path is correct with:
    if ($match = $response->match('/Envelope/Body/command')) {
    $value1 = $response->valueof('//Envelope/Body/command');
    }
    Hope this helps.
      I tried this:
      my $soap = SOAP::Lite->uri($uri)->proxy( $proxyUrl, timeout => 5 ); my $method = SOAP::Data->name("command")->attr( { 'template' => 'sample', 'method' => 'execute', 'loginname' => 'me', } ); my $som = $soap->call($method); if ( $som->fault ) { die $som->fault->faultstring } print $som->valueof('/Envelop/Body/command');
      and then in a debugging session:
      DB<1> x $som->valueof('/Envelope/Body/command') 0 HASH(0x1bb793c) 'message' => HASH(0x1bb793c) -> REUSED_ADDRESS DB<2> x $som->valueof('/Envelope/Body/command/message') 0 HASH(0x1bb793c) 'message' => HASH(0x1bb793c) -> REUSED_ADDRESS
      I cannot see how to access the subnodes ... Thanks for any help! Axel.
        I didn't realise you don't code the request like this:
        $method = SOAP::Data->name('command'=>'value');

        So to access attribute values you should use

        $attr_value = $som->dataof('//Envelope/Body/command')->attr->{'template'};
        or
        $attr_value = $som->dataof('//command')->attr->{'template'};
        (I don't remember which one because don't use attributes.)

        This should hold for
        <Envelope>
        <Body>
        <command template="foo">100</command>
        </Body>
        </Envelope>

        and $attr_value is foo, command value is 100.

        Docs are in SOAP/SOM.pod of perl/site/lib directory.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://629091]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (7)
As of 2020-10-27 16:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My favourite web site is:












    Results (257 votes). Check out past polls.

    Notices?