SOAP::WSDL retrieving output
Posted on 2008-04-23 01:21:25-07 by rhumbliner
I'm sorry, but after my interface call, I just don't know how to retrieve the returned data. my code is as follows:
my $response = $interface->fsPublic_SQL( { # MyTypes::fsPublic_SQLInput QryIn => { StrQuery => $q, option => 'XML', keepRowHeader => 'false', }, },, ); die $response if not $response; print Dumper($response);
the output of the print is:
$response = bless( do{\(my $o = 19)}, 'MyElements::fsPublic_SQLOutput' );
the docs for MyElements::fsPublic_SQLOutput follows:
[~] perldoc MyElements::fsPublic_SQLOutput
DESCRIPTION Perl data type class for the XML Schema defined element fsPublic_SQLOutput from the namespace http://infraweb-dev.fs.usda.gov/fs_public.Services. METHODS new my $element = MyElements::fsPublic_SQLOutput->new($data); Constructor. The following data structure may be passed to new(): { # MyTypes::fsPublic_SQLOutput QryResult => { # MyTypes::QryResult StrHTML => $some_value, # string StrCsv => $some_value, # string StrXML => $some_value, # string }, }, AUTHOR Generated by SOAP::WSDL
i'm stumped as to how to recover the output.
thanks for your patience, tom
Posted on 2008-04-23 11:18:49-07 by mkutter in response to 7724
Use the $obj->get_FOO methods. Just try a name of your choice, and it'll tell you what names are there.
If you need all as a hash ref, you can just use $obj->as_hash_ref()
Martin
Posted on 2008-04-23 15:17:32-07 by rhumbliner in response to 7727
i'm sorry. i must be really obtuse. i've read every line of code generated by wsdl2perl and studied the pod's. i just can't figure out which $obj you're referring to. the main pod shows only 2 objects: $interface and $response.
[~] perldoc MyInterfaces::WSfsPublicQuery::Services_WSfsPublicQuery_Port
NAME MyInterfaces::WSfsPublicQuery::Services_WSfsPublicQuery_Port - SOAP Interface for the WSfsPublicQuery Web Service SYNOPSIS use MyInterfaces::WSfsPublicQuery::Services_WSfsPublicQuery_Port; my $interface = MyInterfaces::WSfsPublicQuery::Services_WSfsPublicQuery_Port->new(); my $response; $response = $interface->fsPublic_SQL(); DESCRIPTION SOAP Interface for the WSfsPublicQuery web service located at http://infrawebdev.fs.usda.gov:5556/ws/fs_public.webService:WSfsPublicQuery.
but when i access $response->get_all() no methods are listed:
Can't locate object method "get_all" via package "MyElements::fsPublic_SQLOutput". Valid methods are: at /usr/lib64/perl5/site_perl/5.8.8/SOAP/WSDL/XSD/Typelib/ComplexType.pm line 42
if i dump $response it tells me i've got the object i think it want. the code print Dumper($response); tells me i've got an object of type fsPublic_SQLOutput but there are no methods to access this object:
$response = bless( do{\(my $o = 19)}, 'MyElements::fsPublic_SQLOutput' );
i'm pretty certain the data is being returned from the server, because if i replace the simple hash in the fsPublic_SQL() call with a MyTypes::fsPublic_SQLInput object the call generates a fault and dumps the entire dataset i'm expecting.
i'm sorry to be a pain, but i'm at a loss to figure this out.
thanks, tom
Posted on 2008-04-23 17:06:05-07 by mkutter in response to 7730
Try $response->_DUMP to get the content of the output object.
You can also look up the class' doc: "perldoc MyElements::fsPublic_SQLOutput" Maybe there just is no content, or it has text content which you can access via ->value();
If there's nothing, but should be, try passing the option "outputxml => 1" to the constructor of the interface class - it should return XML then instead of a response object.
Martin
Posted on 2008-04-23 17:37:52-07 by rhumbliner in response to 7733
the output of `print "_DUMP: ",$response-<_DUMP();` is:
_DUMP: { 'MyTypes::fsPublic_SQLOutput' => { 'QryResult' => bless( do{\(my $o = 20)}, 'MyTypes::QryResult' ) } };
the output of perldoc MyElements::fsPublic_SQLOutput is:
NAME MyElements::fsPublic_SQLOutput DESCRIPTION Perl data type class for the XML Schema defined element fsPublic_SQLOutput from the namespace http://infraweb-dev.fs.usda.gov/fs_public.Services. METHODS new my $element = MyElements::fsPublic_SQLOutput->new($data); Constructor. The following data structure may be passed to new(): { # MyTypes::fsPublic_SQLOutput QryResult => { # MyTypes::QryResult StrHTML => $some_value, # string StrCsv => $some_value, # string StrXML => $some_value, # string }, }, AUTHOR Generated by SOAP::WSDL
which, incidently, puzzles me because why would i want a method to create something that i am expecting as output. shouldn't the pod describe methods to retrieve data from the object?
passing "{outputxml =>1}" as an option to the interface constructor produces xml with the dataset i'm expecting:
$response = '<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> </SOAP-ENV:Header><SOAP-ENV:Body> <ser-root:fsPublic_SQLOutput xmlns:ser-root="http://infrawebdev.fs.usda.gov/fs_public.Services"><QryResult> <StrHTML></StrHTML> <StrCsv></StrCsv> <StrXML> <qryResults> <rows> <ID>04</ID> <NAME>R4, INTERMOUNTAIN REGION</NAME> </rows> ... snip ... </qryResults></StrXML></QryResult></ser-root:fsPublic_SQLOutput></SOAP-ENV:Body> </SOAP-ENV:Envelope>
thanks for walking me thru this, tom
Posted on 2008-04-23 23:50:55-07 by noah in response to 7734
You've already got your response object; in the example from your first post it's '$response'. From this you've got two primary options for mucking with the data;
1) As martin said, call $response->as_hash_ref() which will return a traditional hash reference with which you can work;
2) use the get_-prefixed called your $response object has available. To see which calls it exposes, examine the full error text returned when you call $response->get_nosuchmethod(). Each get_-prefixed call returns an object which references the corresponding tag in the SOAP response. Once you figure out what the first call is, working your way down the tree is just a matter of examining the objects returned from get_(whatever) with _DUMP(). It's a bit hairy the first time through, especially if you're not familiar with how Class::Std(::Fast)? works, but it makes sense.
Noah
Posted on 2008-04-24 03:04:20-07 by rhumbliner in response to 7741
Well i certainly agree with the "hairy" part. ;-)
The problem i'm running into is that i *know* data is coming back because when i create the interface object with {outputxml => 1} i see the data i'm expecting. But when i create $interface normally, then $response->as_hash_ref() returns an empty hash. and $response->get_foo() doesn't return a list of valid calls so i'm stuck there -- i don't have any idea of what methods are available to me. and $response->_DUMP() returns:
{ 'MyTypes::fsPublic_SQLOutput' => { 'QryResult' => bless( do{\(my $o = 20)}, 'MyTypes::QryResult' ) } };
and this still gives me no hints of any methods to use on these objects.
if it was as simple as following objects and their methods down a tree i wouldn't be stuck like this. :-(
is it possible that something is lacking the the wsdl definition? i find it hard to believe that getting a list of valid methods is so difficult.
still grateful for your help,
tom
Posted on 2008-04-25 08:30:39-07 by mkutter in response to 7745
Hi Tom,
actually, it is as simple as following methods down a tree, but you probably just got confused by not seeing anything reasonable in the Data::Dumper output. SOAP::WSDL uses Inside-Out objects, which have several nice features like a memory overhead proportional to the number of class properties, not to the number of objects created (like hash-based objects). However, they're a bit different: They don't show their values in Dumper output, and the _DUMP output is a bit different to read.
$response->get_QryResult();
Should give you the first level response object. And - if nothing has gone wrong - calling any get_FOO method on a object should die with a message like
Can't locate object method "get_FOO" via package "MyTypes::testComplexTypeAll". Valid methods are: get_Test_2, set_Test_2, get_Test_1, set_Test_1 at lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm line 52 SOAP::WSDL::XSD::Typelib::ComplexType::AUTOMETHOD('MyTypes::testComplexTypeAll=SCALAR(0x85bacb4)', 140225716) called at /usr/local/share/perl/5.8.8/Class/Std.pm line 546 Class::Std::AUTOLOAD('MyTypes::testComplexTypeAll=SCALAR(0x85bacb4)') called at t/SOAP/WSDL/Generator/XSD_dot_names.t line 106
The stuff listed in "Valid methods" should give you a hint what to call.
You can also find the list of properties in the pod of the generated classes - the section should read something like this:
PROPERTIES The following properties may be accessed using get_PROPERTY / set_PROPERTY methods: * Test_1 * Test_2
However, you might also have found a bug in SOAP::WSDL, triggering incomplede code generation. But this is - unfortunately - something I cannot tell without examining the WSDL.
Martin
Posted on 2008-04-25 19:55:16-07 by rhumbliner in response to 7764
Now we're getting somewhere! :-) i admit i know next to nothing about Class::Std so I guess I need to read up on that. as i pointed out earlier, calling get_FOO() never returns a list of valid methods, so your example:
Can't locate object method "get_FOO" via package "MyTypes::testComplexTypeAll". Valid methods are: get_Test_2, set_Test_2, get_Test_1, set_Test_1
doesn't apply to me. all i get is a null list:
Can't locate object method "get_FOO" via package "MyTypes::testComplexTypeAll". Valid methods are:
whether this is a bug in SOAP::WSDL or the wsdl i'm using is beyond my capabilities, but i'm happy to let you analyze the wsdl. it's only 79 lines long.
anway, i don't know how you figured out to try the call get_QryResult() but that started me down the path. $response gives me a QryResult object which gives me a StrXML object which gives me a SOAP::WSDL::XSD::Typelib::Builtin::string (i realize QryResult and StrXML are unique to my wsdl). i then just print the string.
so, basically, i think i'm up and running. thanks so much for your help. Drinks are on me next time you're in vegas.
tom
(This article is based on a thread on the CPAN::Forum.)
Published on 2008-04-23