Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Problems with SOAP::Lite client

by thion (Initiate)
on Dec 11, 2008 at 13:41 UTC ( #729686=perlquestion: print w/ replies, xml ) Need Help??
thion has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks, I'm currently writing a soap client, that connects to an IBM tivoli data integrator. Here is the excerpt from the wsdl-file I got: Here are some excerpts from the wsdl-file:
... <element name="updatePLZInformationen"> <complexType> <sequence> <element name="clientid" nillable="true" type="xsd:string" /> <element name="securitytoken" nillable="true" type="xsd:string" /> <element maxOccurs="unbounded" minOccurs="0" name="plzinfos" type="tns2:PLZInfo" /> </sequence> </complexType> </element> ... <complexType name="PLZInfo"> <sequence> <element name="kurzname" nillable="true" type="xsd:string" /> <element name="plz" nillable="true" type="xsd:string" /> <element name="stadt" nillable="true" type="xsd:string" /> <element name="status" nillable="true" type="xsd:string" /> <element name="typ" nillable="true" type="xsd:string" /> <element name="zusatz" nillable="true" type="xsd:string" /> </sequence> </complexType>
And here is my test script:
#!/usr/bin/perl -w use SOAP::Lite +trace => 'debug'; my $plz = SOAP::Lite -> service('file:/home/orca/oracle/DataSyncTool/config/SKADataServ +ice.wsdl'); $plz->updatePLZInformationen(SOAP::Data->type("xsd:string")->name("cli +entid" => "test")->value, SOAP::Data->type("xsd:string")->name("securitytoken" => "test" +)->value, SOAP::Data->type("tns2:PLZInfo")->name("plzinfos")->value( SOAP::Data->name("kurzname")->type("xsd:string")->value( +"gargel"), SOAP::Data->name("plz")->type("xsd:string")->value("1234 +5"), SOAP::Data->name("stadt")->type("xsd:string")->value("Mu +sterstadt"), SOAP::Data->name("status")->type("xsd:string")->value("0 +815"), SOAP::Data->name("typ")->type("xsd:string")->value("2"), SOAP::Data->name("zusatz")->type("xsd:string")->value("h +inten rechts"))->value);
And here goes the soap message:
<?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:wsdlsoap="..." xmlns:tns2="...e" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="..." xmlns:wsdl="..." xmlns:impl="..." xmlns:xsi="..." xmlns:soapenc="..." xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body><impl:updatePLZInformationen> <clientid xsi:type="xsd:string">test</clientid> <securitytoken xsi:type="xsd:string">test</securitytoken> <plzinfos xsi:nil="true" xsi:type="tns2:PLZInfo" /> <-- here's the pro +blem!!! <plz xsi:type="xsd:string">12345</plz> <stadt xsi:type="xsd:string">Musterstadt</stadt> <status xsi:type="xsd:string">0815</status> <typ xsi:type="xsd:string">2</typ> <zusatz xsi:type="xsd:string">hinten rechts</zusatz> </impl:updatePLZInformationen> </soap:Body> </soap:Envelope>
As you can see, the complex type "plzinfos" closes before its variables and not after. What am I doing wrong here?!? Every hint, tip, etc. will be highly appreciated! :-)
Thanks in advance,
Thion

Comment on Problems with SOAP::Lite client
Select or Download Code
Re: Problems with SOAP::Lite client
by Anonymous Monk on Dec 11, 2008 at 15:07 UTC
    Here's one way
    #!/usr/bin/perl -- use strict; use warnings; use SOAP::Lite; use SOAP::Lite 0.65 +trace => 'debug'; my $soap = SOAP::Lite->proxy( 'http://localhost/blah/DummyService' ); my $serializer = $soap->serializer(); print $serializer->envelope( method => 'updatePLZInformationen', SOAP::Data->type("xsd:string")->name( "clientid" => "test" ), SOAP::Data->type("xsd:string")->name( "securitytoken" => "test" ), SOAP::Data->type("tns2:PLZInfo")->name("plzinfos")->value( \SOAP::Data->value( SOAP::Data->name("kurzname")->type("xsd:string")->value("gargel"), SOAP::Data->name("plz")->type("xsd:string")->value("12345"), SOAP::Data->name("stadt")->type("xsd:string")->value("Musterstadt" +), SOAP::Data->name("status")->type("xsd:string")->value("0815"), SOAP::Data->name("typ")->type("xsd:string")->value("2"), SOAP::Data->name("zusatz")->type("xsd:string")->value("hinten rech +ts") ) ) ); __END__ perl soap.lite.729686.pl | xml_pp <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/enc +oding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns: +soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http:/ +/www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSche +ma-instance"> <soap:Body> <updatePLZInformationen> <clientid xsi:type="xsd:string">test</clientid> <securitytoken xsi:type="xsd:string">test</securitytoken> <plzinfos xsi:type="tns2:PLZInfo"> <kurzname xsi:type="xsd:string">gargel</kurzname> <plz xsi:type="xsd:string">12345</plz> <stadt xsi:type="xsd:string">Musterstadt</stadt> <status xsi:type="xsd:string">0815</status> <typ xsi:type="xsd:string">2</typ> <zusatz xsi:type="xsd:string">hinten rechts</zusatz> </plzinfos> </updatePLZInformationen> </soap:Body> </soap:Envelope>
      Hi,

      thanks for the example.

      I tried to build it into my "real" code, but I'm messing up something. I'm reading data from a database here and generate an array of hashes:
      while($sth->fetch()) { my %hash; # Hash zusammenbasteln $hash{"kurzname"} = $kurzname; $hash{"plz"} = $plz; $hash{"stadt"} = $stadt; $hash{"status"} = $status; $hash{"typ"} = $typ; $hash{"zusatz"} = $zusatz; push(@ary,%hash); } $sth->finish(); $dss->updatePLZInformationen(@ary);
      And here is the function that's called and is doing the actual SOAP stuff:
      sub updatePLZInformationen() { my @data = shift; my $plz = SOAP::Lite -> service('file:/home/orca/oracle/DataSyncTool/config/SKADataServ +ice.wsdl'); my $serializer = $plz->serializer(); print($serializer->envelope( method => 'updatePLZInformationen', SOAP::Data->type("xsd:string")->name( "c +lientid" => "test" ), SOAP::Data->type("xsd:string")->name( "s +ecuritytoken" => "test" ), SOAP::Data->type("tns2:PLZInfo")->name(" +plzinfos")->value( \SOAP::Data->value(&format_plz_infos(@ +data))))); $plz->updatePLZInformationen(); } # -------------------------------------------------------------------- +---------------------------- # sub format_plz_infos() { my @plz = shift(); my @plz_info; foreach(@plz) { my $hash = $_; push(@plz_info,SOAP::Data->name("kurzname")->value($hash->{"ku +rzname"})->type("xsd:string")); push(@plz_info,SOAP::Data->name("plz")->value($hash->{"plz"})- +>type("xsd:string")); push(@plz_info,SOAP::Data->name("stadt")->value($hash->{"stadt +"})->type("xsd:string")); push(@plz_info,SOAP::Data->name("status")->value($hash->{"stat +us"})->type("xsd:string")); push(@plz_info,SOAP::Data->name("typ")->value($hash->{"typ"})- +>type("xsd:string")); push(@plz_info,SOAP::Data->name("zusatz")->value($hash->{"zusa +tz"})->type("xsd:string")); } return(@plz_info); } # -------------------------------------------------------------------- +---------------------------- #
      And this is my SOAP-message:
      ?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body><updatePLZInformationen> <clientid xsi:type="xsd:string">test</clientid> <securitytoken xsi:type="xsd:string">test</securitytoken> <plzinfos xsi:type="tns2:PLZInfo"> <kurzname xsi:nil="true" xsi:type="xsd:string" /> <plz xsi:nil="true" xsi:type="xsd:string" /> <stadt xsi:nil="true" xsi:type="xsd:string" /> <status xsi:nil="true" xsi:type="xsd:string" /> <typ xsi:nil="true" xsi:type="xsd:string" /> <zusatz xsi:nil="true" xsi:type="xsd:string" /> </plzinfos> </updatePLZInformationen> </soap:Body> </soap:Envelope>
      The message looks good, but it has no values... I'm reading my code for about an hour now, but I don't seem to get the mistake. :-(

      Thanks in advance,

      Thion
        That is confusing. Instead of this
        push(@ary,%hash);
        you probably meant
        push @ary, \%hash;
        but then you probably meant
        $dss->updatePLZInformationen(%hash);
        instead. I could probably guess what you're really after, but its better if you pseudocode/diagram what you wish to accomplish, before writing actual code.
Re: Problems with SOAP::Lite client
by alexlc (Beadle) on Dec 12, 2008 at 03:20 UTC
    SOAP::WSDL is worth a try. It removes the necessity to hand encode each value.
    It doesn't parse all wsdl files though, so your mileage may vary.
    There is a 1.27 branch, and 2.0 branch. 2.0 looks promising, though I typically have better luck with 1.27.
    -- AlexLC
Re: Problems with SOAP::Lite client
by klekker (Pilgrim) on Dec 15, 2008 at 08:44 UTC
    Have you tried SOAP::Data::Builder already? I have had similar problems with a 'complex' data structure and could solve it by using this module.

    k
      No, that would have been my next move, but the example provided by AnonymousMonk already did the job, so I stuck with it.

      Regards,

      Thion
        My basic question is how does request know the proxy address when we give just the wsdl file name/location.?

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (6)
As of 2015-07-05 22:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (68 votes), past polls