in reply to Which version of Soap::Lite for writing document/literal web services?

We use SOAP::Lite (both server and client) quite extensively. Recently we upgraded to 0.69 (currently the latest version I think) and things went wrong.

Except of some inconsistencies in our code, which were tolerated by the old version of SOAP::Lite, I found two quite serious errors:

Nevertheless we still use 0.69, even for document/literal SOAP. To have full control over the content of soap body element I often use $soap->call with the method argument being a XML (XML::LibXML) document (complete content of the soap:Body element).

my $som = $soap->call(soap_xml_data $xml_doc);
sub soap_xml_data { my ($value) = @_; return Akar::SOAP::Data::XMLLiteral->new_data($value); } package Akar::SOAP::Data::XMLLiteral; use strict; use SOAP::Lite; our @ISA = qw(SOAP::Data); # the constructor new_data to avoid conflict with SOAP::Data->new sub new_data { my ( $package, $value ) = @_; # value can be text, XML::LibXML::Document, XML::LibXML::Element my $node = !ref($value) ? XML::LibXML->new->parse_string($value)->documen +tElement : UNIVERSAL::isa( $value, 'XML::LibXML::Element' ) ? $value : UNIVERSAL::isa( $value, 'XML::LibXML::Document' ) ? $value->documentElement : die "Invalid param of XML data\n "; # 2007-09-12 danielr, I guess that the text for SOAP::Lite # should be byt not character UTF8 otherwise # Wide character error occur as it was in cabernet my $text = $node->toString; if (Encode::is_utf8($text)){ $text = Encode::encode('utf-8', $text); } my $data = SOAP::Data->new( 'type' => 'xml', 'value' => $text, 'name' => $node->localname, 'prefix' => $node->prefix, 'uri' => $node->namespaceURI, ); return bless $data => $package; } # object can't be broken by set_value sub set_value { return shift(); }

On the server site I use similar approach to return the complete content of soap:Body element.

sub dispatched_method { .... return soap_response_body(soap_xml_data($xml_doc)); }

This approach contains an ugly hack, which prevents SOAP::Lite serializer to wrap the returned value by a response element.

sub soap_response_body { my ($soap_data) = @_; return Akar::SOAP::Data::ResponseBody->new_data($soap_data); } package Akar::SOAP::Data::ResponseBody; .... my $orig_envelope_sub = \&SOAP::Serializer::envelope; no warnings 'redefine'; *SOAP::Serializer::envelope = sub { # if the only value returned is xml data then # method name (parameter 2) is removed from the parameter list if ( $_[1] eq 'response' && UNIVERSAL::isa( $_[3], __PACKAGE__ ) && @_ == 4 ) { splice( @_, 2, 1); } goto $orig_envelope_sub; };