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

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="" xmlns:soap="..." xmlns:wsdl="..." xmlns:impl="..." xmlns:xsi="..." xmlns:soapenc="..." xmlns:xsd=""> <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,

Replies are listed 'Best First'.
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 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 | xml_pp <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope soap:encodingStyle=" +oding/" xmlns:soap="" xmlns: +soapenc="" xmlns:xsd="http:/ +/" xmlns:xsi=" +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>

      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="" xmlns:soapenc="" xmlns:xsd="" soap:encodingStyle="" xmlns:soap=""> <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,

        That is confusing. Instead of this
        you probably meant
        push @ary, \%hash;
        but then you probably meant
        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 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.

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


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

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://729686]
Approved by svenXY
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2018-05-23 07:47 GMT
Find Nodes?
    Voting Booth?