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

I am finding Soap::Lite is skipping the first parameter and generating an extra unwanted definition:
<OpGetList xsi:nil="true" xsi:type="s0:GetListInputMap" />
I suspect it is due to the fact I don't understand why the heck it wants to put the stupid defn there and I couldn't find an RTFM that made sense. The code:
my $soapHndl = SOAP::Lite->new()->service($wsdl)->readable(1)->on_faul +t(\&SoapErrorHandler); my @queryObj = (SOAP::Data->type('string')->name('startRecord'=>$START +RECORD), SOAP::Data->type('string')->name('maxLimit'=>$MAXLIMIT), SOAP::Header->name('AuthenticationInfo')->value( \SOAP::Header->value( ( SOAP::Header->name('userName')->value('xx'), SOAP::Header->name('password')->value('xx') ) ) ) ); my @RemedyList = $soapHndl->OpGetList(@queryObj);
Generates bogus XML:
<?xml version="1.0" encoding="UTF-8"?> <soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:s0="urn:HD_Netcool_v1"> <soap:Header> <AuthenticationInfo> <userName xsi:type="xsd:string">xx</userName> <password xsi:type="xsd:string">xx</password> </AuthenticationInfo> </soap:Header> <soap:Body> <s0:OpGetList> BAD LINE>> <OpGetList xsi:nil="true" xsi:type="s0:GetListInputMap +" /> <startRecord xsi:type="xsd:string">0</startRecord> <maxLimit xsi:type="xsd:string">10</maxLimit> </s0:OpGetList> </soap:Body> </soap:Envelope>
To work around the problem I used stubmaker.pl to create the PM and commented out the parameter line in the method. Then the code generates fine. I tracked down where the XML was generated within the module using the service() method but I couldn't figure out if there was a method call that could turn off the behavior. Also, I couldn't quite make heads or tails of why the line was there to begin with.
The virtual PM is build via "generate_stub(/usr/lib/perl5/site_perl/5. +8.8/SOAP/Lite.pm:3264" foreach (@{$services->{$service}{parameters}}) { # This is a workaround for https://sourceforge.net/tracker +/index.php?func=detail&aid=2001592&group_id=66000&atid=513017 next unless ref $_; $self->{'_stub'} .= " SOAP::Data->new(name => '".$_-> +name."', type => '".$_->type."', attr => {"; $self->{'_stub'} .= do { my %attr = %{$_->attr}; join(', ', map {"'$_' => '$attr{$_}'"} grep {/^xmlns:(?!-)/} keys %attr); }; $self->{'_stub'} .= "}),\n"; } Builds: SOAP::Schema::generate_stub(/usr/lib/perl5/site_perl/5.8.8/SOAP/Lite.p +m:3270): 3270: join(', ', map {"'$_' => '$attr{$_}'"} DB<136> p $self->{'_stub'} package HD_Netcool_v1Service; # Generated by SOAP::Lite (v0.712) for Perl -- soaplite.com # Copyright (C) 2000-2006 Paul Kulchenko, Byrne Reese # -- generated at [Thu Apr 7 10:57:38 2011] # -- generated from http://stsnymidrem2dr/arsys/WSDL/public/devsupport +/HD_Netcool_v1 my %methods = ( OpSet => { endpoint => 'http://stsnymidrem2dr/arsys/services/ARService?server +=devsupport&webService=HD_Netcool_v1', soapaction => 'urn:HD_Netcool_v1/OpSet', namespace => 'urn:HD_Netcool_v1', parameters => [ SOAP::Data->new(name => 'OpSet', type => 's0:SetInputMap', attr +=> { DB<163> p Data::Dumper->Dumper($services->{$service}{parameters}[0]{_a +ttr}) $VAR1 = 'Data::Dumper'; $VAR2 = { 'name' => 'OpGetList', 'type' => 's0:GetListInputMap' };
The FULL wsdl including the method used above is as follows:
<wsdl:definitions targetNamespace="urn:HD_Netcool_v1"> <wsdl:types> <xsd:schema elementFormDefault="qualified" targetNamespace="urn:HD_Net +cool_v1"> <xsd:element name="OpGet" type="s0:GetInputMap"/> <xsd:complexType name="GetInputMap"> <xsd:sequence> <xsd:element name="Request_ID" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:element name="OpGetResponse" type="s0:GetOutputMap"/> <xsd:complexType name="GetOutputMap"> <xsd:sequence> <xsd:element name="Assigned_To" type="xsd:string"/> <xsd:element name="assigned_group" type="xsd:string"/> <xsd:element name="Create_Date" type="xsd:dateTime"/> <xsd:element name="Last_Modified_By" type="xsd:string"/> <xsd:element name="Modified_Date" type="xsd:dateTime"/> <xsd:element name="nc_alertgroup" type="xsd:string"/> <xsd:element name="nc_alertkey" type="xsd:string"/> <xsd:element name="nc_customer" type="xsd:string"/> <xsd:element name="nc_ipcname" type="xsd:string"/> <xsd:element name="nc_ipcstatus" type="xsd:string"/> <xsd:element name="nc_location" type="xsd:string"/> <xsd:element name="nc_node" type="xsd:string"/> <xsd:element name="nc_nodealias" type="xsd:string"/> <xsd:element name="nc_region" type="xsd:string"/> <xsd:element name="nc_severity" type="xsd:int"/> <xsd:element name="nc_summary" type="xsd:string"/> <xsd:element name="Request_ID" type="xsd:string"/> <xsd:element name="Short_Description" type="xsd:string"/> <xsd:element name="Status" type="s0:StatusType"/> <xsd:element name="Status_History" type="xsd:string"/> <xsd:element name="Submitter" type="xsd:string"/> <xsd:element name="ucn" type="xsd:string"/> <xsd:element name="zassignedgroupid" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:simpleType name="StatusType"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="unprocessed"/> <xsd:enumeration value="processed"/> </xsd:restriction> </xsd:simpleType> <xsd:element name="OpService" type="s0:ServiceInputMap"/> <xsd:complexType name="ServiceInputMap"> <xsd:sequence> <xsd:element name="Assigned_To" type="xsd:string"/> <xsd:element name="assigned_group" type="xsd:string"/> <xsd:element name="nc_alertgroup" type="xsd:string"/> <xsd:element name="nc_alertkey" type="xsd:string"/> <xsd:element name="nc_customer" type="xsd:string"/> <xsd:element name="nc_ipcname" type="xsd:string"/> <xsd:element name="nc_ipcstatus" type="xsd:string"/> <xsd:element name="nc_location" type="xsd:string"/> <xsd:element name="nc_node" type="xsd:string"/> <xsd:element name="nc_nodealias" type="xsd:string"/> <xsd:element name="nc_region" type="xsd:string"/> <xsd:element name="nc_severity" type="xsd:int"/> <xsd:element name="nc_summary" type="xsd:string"/> <xsd:element name="Short_Description" type="xsd:string"/> <xsd:element name="Status" type="s0:StatusType"/> <xsd:element name="Submitter" type="xsd:string"/> <xsd:element name="ucn" type="xsd:string"/> <xsd:element name="zassignedgroupid" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:element name="OpServiceResponse" type="s0:ServiceOutputMap"/> <xsd:complexType name="ServiceOutputMap"> <xsd:sequence> <xsd:element name="Assigned_To" type="xsd:string"/> <xsd:element name="assigned_group" type="xsd:string"/> <xsd:element name="Create_Date" type="xsd:dateTime"/> <xsd:element name="Last_Modified_By" type="xsd:string"/> <xsd:element name="Modified_Date" type="xsd:dateTime"/> <xsd:element name="nc_alertgroup" type="xsd:string"/> <xsd:element name="nc_alertkey" type="xsd:string"/> <xsd:element name="nc_customer" type="xsd:string"/> <xsd:element name="nc_ipcname" type="xsd:string"/> <xsd:element name="nc_ipcstatus" type="xsd:string"/> <xsd:element name="nc_location" type="xsd:string"/> <xsd:element name="nc_node" type="xsd:string"/> <xsd:element name="nc_nodealias" type="xsd:string"/> <xsd:element name="nc_region" type="xsd:string"/> <xsd:element name="nc_severity" type="xsd:int"/> <xsd:element name="nc_summary" type="xsd:string"/> <xsd:element name="Request_ID" type="xsd:string"/> <xsd:element name="Short_Description" type="xsd:string"/> <xsd:element name="Status" type="s0:StatusType"/> <xsd:element name="Status_History" type="xsd:string"/> <xsd:element name="Submitter" type="xsd:string"/> <xsd:element name="ucn" type="xsd:string"/> <xsd:element name="zassignedgroupid" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:element name="OpCreate" type="s0:CreateInputMap"/> <xsd:complexType name="CreateInputMap"> <xsd:sequence> <xsd:element name="Assigned_To" type="xsd:string"/> <xsd:element name="assigned_group" type="xsd:string"/> <xsd:element name="nc_alertgroup" type="xsd:string"/> <xsd:element name="nc_alertkey" type="xsd:string"/> <xsd:element name="nc_customer" type="xsd:string"/> <xsd:element name="nc_ipcname" type="xsd:string"/> <xsd:element name="nc_ipcstatus" type="xsd:string"/> <xsd:element name="nc_location" type="xsd:string"/> <xsd:element name="nc_node" type="xsd:string"/> <xsd:element name="nc_nodealias" type="xsd:string"/> <xsd:element name="nc_region" type="xsd:string"/> <xsd:element name="nc_severity" type="xsd:int"/> <xsd:element name="nc_summary" type="xsd:string"/> <xsd:element name="Short_Description" type="xsd:string"/> <xsd:element name="Status" type="s0:StatusType"/> <xsd:element name="Submitter" type="xsd:string"/> <xsd:element name="ucn" type="xsd:string"/> <xsd:element name="zassignedgroupid" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:element name="OpCreateResponse" type="s0:CreateOutputMap"/> <xsd:complexType name="CreateOutputMap"> <xsd:sequence> <xsd:element name="Request_ID" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:element name="OpGetList" type="s0:GetListInputMap"/> <xsd:complexType name="GetListInputMap"> <xsd:sequence> <xsd:element name="Qualification" type="xsd:string"/> <xsd:element name="startRecord" type="xsd:string"/> <xsd:element name="maxLimit" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:element name="OpGetListResponse" type="s0:GetListOutputMap"/> <xsd:complexType name="GetListOutputMap"> <xsd:sequence> <xsd:element maxOccurs="unbounded" name="getListValues"> <xsd:complexType> <xsd:sequence> <xsd:element name="Assigned_To" type="xsd:string"/> <xsd:element name="assigned_group" type="xsd:string"/> <xsd:element name="Create_Date" type="xsd:dateTime"/> <xsd:element name="Last_Modified_By" type="xsd:string"/> <xsd:element name="Modified_Date" type="xsd:dateTime"/> <xsd:element name="nc_alertgroup" type="xsd:string"/> <xsd:element name="nc_alertkey" type="xsd:string"/> <xsd:element name="nc_customer" type="xsd:string"/> <xsd:element name="nc_ipcname" type="xsd:string"/> <xsd:element name="nc_ipcstatus" type="xsd:string"/> <xsd:element name="nc_location" type="xsd:string"/> <xsd:element name="nc_node" type="xsd:string"/> <xsd:element name="nc_nodealias" type="xsd:string"/> <xsd:element name="nc_region" type="xsd:string"/> <xsd:element name="nc_severity" type="xsd:int"/> <xsd:element name="nc_summary" type="xsd:string"/> <xsd:element name="Request_ID" type="xsd:string"/> <xsd:element name="Short_Description" type="xsd:string"/> <xsd:element name="Status" type="s0:StatusType"/> <xsd:element name="Status_History" type="xsd:string"/> <xsd:element name="Submitter" type="xsd:string"/> <xsd:element name="ucn" type="xsd:string"/> <xsd:element name="zassignedgroupid" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> <xsd:element name="OpSet" type="s0:SetInputMap"/> <xsd:complexType name="SetInputMap"> <xsd:sequence> <xsd:element name="Assigned_To" type="xsd:string"/> <xsd:element name="assigned_group" type="xsd:string"/> <xsd:element name="nc_alertgroup" type="xsd:string"/> <xsd:element name="nc_alertkey" type="xsd:string"/> <xsd:element name="nc_customer" type="xsd:string"/> <xsd:element name="nc_ipcname" type="xsd:string"/> <xsd:element name="nc_ipcstatus" type="xsd:string"/> <xsd:element name="nc_location" type="xsd:string"/> <xsd:element name="nc_node" type="xsd:string"/> <xsd:element name="nc_nodealias" type="xsd:string"/> <xsd:element name="nc_region" type="xsd:string"/> <xsd:element name="nc_severity" type="xsd:int"/> <xsd:element name="nc_summary" type="xsd:string"/> <xsd:element name="Short_Description" type="xsd:string"/> <xsd:element name="Status" type="s0:StatusType"/> <xsd:element name="Submitter" type="xsd:string"/> <xsd:element name="ucn" type="xsd:string"/> <xsd:element name="zassignedgroupid" type="xsd:string"/> <xsd:element name="Request_ID" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:element name="OpSetResponse" type="s0:SetOutputMap"/> <xsd:complexType name="SetOutputMap"> <xsd:sequence/> </xsd:complexType> <xsd:element name="AuthenticationInfo" type="s0:AuthenticationInfo"/> <xsd:complexType name="AuthenticationInfo"> <xsd:sequence> <xsd:element name="userName" type="xsd:string"/> <xsd:element name="password" type="xsd:string"/> <xsd:element minOccurs="0" name="authentication" type="xsd:string"/> <xsd:element minOccurs="0" name="locale" type="xsd:string"/> <xsd:element minOccurs="0" name="timeZone" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:schema> </wsdl:types> <wsdl:message name="OpCreateSoapOut"> <wsdl:part element="s0:OpCreateResponse" name="parameters"/> </wsdl:message> <wsdl:message name="ARAuthenticate"> <wsdl:part element="s0:AuthenticationInfo" name="parameters"/> </wsdl:message> <wsdl:message name="OpServiceSoapOut"> <wsdl:part element="s0:OpServiceResponse" name="parameters"/> </wsdl:message> <wsdl:message name="OpSetSoapOut"> <wsdl:part element="s0:OpSetResponse" name="parameters"/> </wsdl:message> <wsdl:message name="OpCreateSoapIn"> <wsdl:part element="s0:OpCreate" name="parameters"/> </wsdl:message> <wsdl:message name="OpGetSoapOut"> <wsdl:part element="s0:OpGetResponse" name="parameters"/> </wsdl:message> <wsdl:message name="OpServiceSoapIn"> <wsdl:part element="s0:OpService" name="parameters"/> </wsdl:message> <wsdl:message name="OpGetListSoapOut"> <wsdl:part element="s0:OpGetListResponse" name="parameters"/> </wsdl:message> <wsdl:message name="OpGetSoapIn"> <wsdl:part element="s0:OpGet" name="parameters"/> </wsdl:message> <wsdl:message name="OpGetListSoapIn"> <wsdl:part element="s0:OpGetList" name="parameters"/> </wsdl:message> <wsdl:message name="OpSetSoapIn"> <wsdl:part element="s0:OpSet" name="parameters"/> </wsdl:message> <wsdl:portType name="PortPortType"> <wsdl:operation name="OpGet"> <wsdl:input message="s0:OpGetSoapIn"/> <wsdl:output message="s0:OpGetSoapOut"/> </wsdl:operation> <wsdl:operation name="OpService"> <wsdl:input message="s0:OpServiceSoapIn"/> <wsdl:output message="s0:OpServiceSoapOut"/> </wsdl:operation> <wsdl:operation name="OpCreate"> <wsdl:input message="s0:OpCreateSoapIn"/> <wsdl:output message="s0:OpCreateSoapOut"/> </wsdl:operation> <wsdl:operation name="OpGetList"> <wsdl:input message="s0:OpGetListSoapIn"/> <wsdl:output message="s0:OpGetListSoapOut"/> </wsdl:operation> <wsdl:operation name="OpSet"> <wsdl:input message="s0:OpSetSoapIn"/> <wsdl:output message="s0:OpSetSoapOut"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="PortSoapBinding" type="s0:PortPortType"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/s +oap/http"/> <wsdl:operation name="OpGet"> <soap:operation soapAction="urn:HD_Netcool_v1/OpGet" style="document"/ +> <wsdl:input> <soap:header message="s0:ARAuthenticate" part="parameters" use="litera +l"> </soap:header> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="OpService"> <soap:operation soapAction="urn:HD_Netcool_v1/OpService" style="docume +nt"/> <wsdl:input> <soap:header message="s0:ARAuthenticate" part="parameters" use="litera +l"> </soap:header> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="OpCreate"> <soap:operation soapAction="urn:HD_Netcool_v1/OpCreate" style="documen +t"/> <wsdl:input> <soap:header message="s0:ARAuthenticate" part="parameters" use="litera +l"> </soap:header> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="OpGetList"> <soap:operation soapAction="urn:HD_Netcool_v1/OpGetList" style="docume +nt"/> <wsdl:input> <soap:header message="s0:ARAuthenticate" part="parameters" use="litera +l"> </soap:header> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="OpSet"> <soap:operation soapAction="urn:HD_Netcool_v1/OpSet" style="document"/ +> <wsdl:input> <soap:header message="s0:ARAuthenticate" part="parameters" use="litera +l"> </soap:header> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="HD_Netcool_v1Service"> <wsdl:port binding="s0:PortSoapBinding" name="PortSoap"> <soap:address location="http://stsnymidrem2dr/arsys/services/ARService +?server=devsupport&webService=HD_Netcool_v1"/> </wsdl:port> </wsdl:service> </wsdl:definitions>

Replies are listed 'Best First'.
Re: Soap::Lite and Extra XML Definitions...
by dneedles (Sexton) on Apr 07, 2011 at 22:17 UTC
    Okay this was a SOAP newbe error. Very difficult to find btw. It is not well documented in SOAP::Lite (probably because it is common XML knowledge) but the reason for the premature complex type termination was:

    Complex types must be explicitly dereferenced.

    Once this was corrected then none of the parameters showed up. This is also not well documented but the order of the ARRAY much be: METHOD, BODY, HEADER. DO NOT LEAVE ANYTHING OUT even if you call the method with the array. The corrected array:
    @queryObj = ( method => 'OpGetList', SOAP::Data->type('s0:GetListInputMap')->name('OpGetList')->value +( \SOAP::Data->value( SOAP::Data->type('string')->name('Qualification'=>$QUERY), SOAP::Data->type('string')->name('startRecord'=>$STARTRECORD +), SOAP::Data->type('string')->name('maxLimit'=>$MAXLIMIT), ) ), SOAP::Header->name('AuthenticationInfo')->value( \SOAP::Header->value( ( SOAP::Header->name('userName')->value('xxx'), SOAP::Header->name('password')->value('xxx') ) )
      Arg. I spoke too soon. Though it now properly lists the parameters, it still also includes a terminated OpGetList. I do not get the appeal of SOAP. It is way too complicated and verbose for what it is trying to do. It's like doing math in Roman Numerals. That stalled math from about 0 until 1400. 8-P

      <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:s0="urn:HD_Netcool_v1"> <soap:Header> <AuthenticationInfo> <userName xsi:type="xsd:string">xx</userName> <password xsi:type="xsd:string">xx</password> </AuthenticationInfo> </soap:Header> <soap:Body> <s0:OpGetList> <OpGetList xsi:nil="true" xsi:type="s0:GetListInputMap" /> <c-gensym8 xsi:type="xsd:string">OpGetList</c-gensym8> <OpGetList xsi:type="s0:GetListInputMap"> <Qualification xsi:type="xsd:string">'Submitter'="RemedyTicket +"</Qual ification> <startRecord xsi:type="xsd:string">0</startRecord> <maxLimit xsi:type="xsd:string">10</maxLimit> </OpGetList> </s0:OpGetList> </soap:Body> </soap:Envelope>