Provided by: libsoap-lite-perl_1.27-1_all bug


       SOAP::Serializer - the means by which the toolkit manages the expression of data as XML


       The SOAP::Serializer class is the means by which the toolkit manages the expression of
       data as XML. The object that a SOAP::Lite instance uses by default is generally enough for
       the task, with no need for the application to create its own. The main purpose of this
       class is to provide a place for applications to extend the serializer by defining
       additional methods for handling new datatypes.


       new(optional key/value pairs)
               $serialize = SOAP::Serializer->new( );

           This is the constructor method for the class. In addition to creating a basic object
           and initializing it with default values, the constructor can also take names and
           values for most of the accessor methods that the class supports.

       envelope(method, data arguments)
               $serialize->envelope(fault => $fault_obj);

           Provides the core purpose for the SOAP::Serializer class. It creates the full SOAP
           envelope based on the input passed in to it. The data arguments passed in the list of
           parameters to the method are divided into two sublists: any parameters that are
           SOAP::Header objects or derivatives of go into one list, while the remainder go into
           the other. The nonheader objects are used as the content for the message body, with
           the body itself being largely dependent on the value of the first argument in the
           list. This argument is expected to be a string and should be one of the following:


           This provides access to the calling context of "SOAP::Serializer". In a client side
           context the often means a reference to an instance of SOAP::Lite. In a server side
           context this means a reference to a SOAP::Server instance.

               The envelope is being created to encapsulate a RPC-style method call.

               The message being created is that of a response stemming from a RPC-style method

               For this specifier, the envelope being created is to transmit a fault.

               This identifier is used as a general-case encoding style for messages that don't
               fit into any of the previous cases. The arguments are encoded into the envelope's
               Body tag without any sort of context sensitivity.

           Any value other than these four results in an error.

       envprefix(optional value)

           Gets or sets the prefix that labels the SOAP envelope namespace. This defaults to

       encprefix(optional value)

           Gets or sets the prefix that labels the SOAP encoding namespace. Defaults to SOAP-ENC.

       soapversion(optional value)

           If no parameter is given, returns the current version of SOAP that is being used as
           the basis for serializing messages. If a parameter is given, attempts to set that as
           the version of SOAP being used. The value should be either 1.1 or 1.2. When the SOAP
           version is being set, the package selects new URNs for envelope and encoding spaces
           and also calls the xmlschema method to set the appropriate schema definition.

       xmlschema(optional value)

           Gets or sets the URN for the schema being used to express the structure of the XML
           generated by the serializer. If setting the value, the input must be the full URN for
           the new schema and is checked against the list of known SOAP schemas.

           The register_ns subroutine allows users to register a global namespace with the SOAP
           Envelope. The first parameter is the namespace, the second parameter to this
           subroutine is an optional prefix. If a prefix is not provided, one will be generated
           automatically for you. All namespaces registered with the serializer get declared in
           the <soap:Envelope /> element.

           The find_prefix subroutine takes a namespace as a parameter and returns the assigned
           prefix to that namespace. This eliminates the need to declare and redeclare namespaces
           within an envelope. This subroutine is especially helpful in determining the proper
           prefix when assigning a type to a SOAP::Data element. A good example of how this might
           be used is as follows:

               SOAP::Data->name("foo" => $inputParams{'foo'})


       When serializing an object, or blessed hash reference, into XML, "SOAP::Serializer" first
       checks to see if a subroutine has been defined for the corresponding class name. For
       example, in the code below, "SOAP::Serializer" will check to see if a subroutine called
       "as_MyModule__MyPackage" has been defined. If so, then it will pass $foo to that
       subroutine along with other data known about the "SOAP::Data" element being encoded.

          $foo = MyModule::MyPackage->new;
          my $client = SOAP::Lite
          $som = $client->someMethod(SOAP::Data->name("foo" => $foo));


       Naming Convention
           The subroutine should always be prepended with "as_" followed by the type's name. The
           type's name must have all colons (':') substituted with an underscore ('_').

           The input to "as_TypeName" will have at least one parameter, and at most four
           parameters. The first parameter will always be the value or the object to be encoded.
           The following three parameters depend upon the context of the value/object being

           If the value/object being encoded was part of a "SOAP::Data" object (as in the above
           example), then the second, third and fourth parameter will be the "SOAP::Data"
           element's name, type, and attribute set respectively. If on the other hand, the
           value/object being encoded is not part of a "SOAP::Data" object, as in the code below:

              $foo = MyModule::MyPackage->new;
              my $client = SOAP::Lite
              $som = $client->someMethod($foo);

           Then the second and third parameters will be the class name of the value/object being
           encoded (e.g. "MyModule::MyPackage" in the example above), and the fourth parameter
           will be an empty hash.

           The encoding subroutine must return an array containing three elements: 1) the name of
           the XML element, 2) a hash containing the attributes to be placed into the element,
           and 3) the value of the element.


       When the type of an element has not been declared explicitly, SOAP::Lite must "guess" at
       the object's type. That is due to the fact that the only form of introspection that Perl
       provides (through the use of the "ref" subroutine) does not provide enough information to
       "SOAP::Serializer" to allow SOAP::Lite to determine the exact type of an element being

       To work around this limitation, the "SOAP::Serializer::typelookup" hash was created. This
       hash is populated with all the data types that the current "SOAP::Serializer" can auto
       detect. Users and developers are free to modify the contents of this hash allowing them to
       register new data types with the system.

       When "SOAP::Serializer" is asked to encode an object into XML, it goes through the
       following steps. First, "SOAP::Serializer" checks to see if a type has been explicitly
       stated for the current object. If a type has been provided "SOAP::Serializer" checks to
       see if an "as_TypeName" subroutine as been defined for that type. If such a subroutine
       exists, then "SOAP::Serializer" passes the object to it to be encoded. If the subroutine
       does not exist, or the type has not been provided, then "SOAP::Serializer" must attempt to
       "guess" the type of the object being serialized.

       To do so, "SOAP::Serializer" runs in sequence a set of tests stored in the
       "SOAP::Serializer::typelookup" hash. "SOAP::Serializer" continues to run each test until
       one of the tests returns true, indicating that the type of the object has been detected.
       When the type of the object has been detected, then "SOAP::Serializer" passes the object
       to the encoding subroutine that corresponds with the test that was passed. If all the
       tests fail, and the type was not determined, then "SOAP::Serializer" will as a last resort
       encode the object based on one of the four basic data types known to Perl: REF, SCALAR,
       ARRAY and HASH.

       The following table contains the set of data types detectable by "SOAP::Lite" by default
       and the order in which their corresponding test subroutine will be run, according to their
       precedence value.

         Table 1 - Autotyping Precedence

         base64      10
         int         20
         long        25
         float       30
         gMonth      35
         gDay        40
         gYear       45
         gMonthDay   50
         gYearMonth  55
         date        60
         time        70
         dateTime    75
         duration    80
         boolean     90
         anyURI      95
         string      100

       To register a new data type that can be automatically detected by "SOAP::Lite" and then
       serialized into XML, the developer must provide the following four things:

       ·   The name of the new data type.

       ·   A subroutine that is capable of detecting whether a value passed to it is of the
           corresponding data type.

       ·   A number representing the test subroutine's precedence relative to all the other
           types' test subroutinestypes. See Table 1 - Autotyping Precedence.

       ·   A subroutine that is capable of providing "SOAP::Serializer" with the information
           necessary to serialize an object of the corresponding data type into XML.

       EXAMPLE 1

       If, for example, you wish to create a new datatype called "uriReference" for which you
       would like Perl values to be automatically detected and serialized into, then you follow
       these steps.

       Step 1: Write a Test Subroutine

       The test subroutine will have passed to it by "SOAP::Serializer" a value to be tested. The
       test subroutine must return 1 if the value passed to it is of the corresponding type, or
       else it must return 0.

           sub SOAP::Serializer::uriReferenceTest {
             my ($value) = @_;
             return 1 if ($value =~ m!^http://!);
             return 0;

       Step 2: Write an Encoding Subroutine

       The encoding subroutine provides "SOAP::Serializer" with the data necessary to encode the
       value passed to it into XML. The encoding subroutine name's should be of the following
       format: "as_"<Type Name>.

       The encoding subroutine will have passed to it by "SOAP::Serializer" four parameters: the
       value to be encoded, the name of the element being encoded, the assumed type of the
       element being encoded, and a reference to a hash containing the attributes of the element
       being encoded. The encoding subroutine must return an array representing the encoded
       datatype. "SOAP::Serializer" will use the contents of this array to generate the
       corresponding XML of the value being encoded, or serialized. This array contains the
       following 3 elements: the name of the XML element, a hash containing the attributes to be
       placed into the element, and the value of the element.

         sub SOAP::Serializer::as_uriReference {
           my $self = shift;
           my($value, $name, $type, $attr) = @_;
           return [$name, {'xsi:type' => 'xsd:uriReference', %$attr}, $value];

       Step 3: Register the New Data Type

       To register the new data type, simply add the type to the "SOAP::Serializer::typelookup"
       hash using the type name as the key, and an array containing the precedence value, the
       test subroutine, and the encoding subroutine.

             = [11, \&uriReferenceTest, 'as_uriReference'];

       Tip: As a short hand, you could just as easily use an anonymous test subroutine when
       registering the new datatype in place of the "urlReferenceTest" subroutine above. For

             = [11, sub { $_[0] =~ m!^http://! }, 'as_uriReference'];

       Once complete, "SOAP::Serializer" will be able to serialize the following "SOAP::Data"
       object into XML:

         $elem = SOAP::Data->name("someUri" => '')->type('uriReference');

       "SOAP::Serializer" will also be able to automatically determine and serialize the
       following untyped "SOAP::Data" object into XML:

         $elem = SOAP::Data->name("someUri" => '');


       Special thanks to O'Reilly publishing which has graciously allowed SOAP::Lite to republish
       and redistribute large excerpts from Programming Web Services with Perl, mainly the
       SOAP::Lite reference found in Appendix B.


       Copyright (C) 2000-2004 Paul Kulchenko. All rights reserved.

       This library is free software; you can redistribute it and/or modify it under the same
       terms as Perl itself.


       Paul Kulchenko (

       Randy J. Ray (

       Byrne Reese (