NAME

SOAP::Parser - Parses SOAP documents

SYNOPSIS

    use SOAP::Parser;
  
    my $parser = SOAP::Parser->new();
    $parser->parsefile('soap.xml');
    my $headers = $parser->get_headers();
    my $body    = $parser->get_body();

DESCRIPTION

SOAP::Parser has all the logic for traversing a SOAP packet, including Envelope, Header, and Body, dealing with namespaces and tracking down references. It is basically an extension of a SAX-like parser, which means that it exposes an event-driven interface that you can implement to get the results of the parse. By default, SOAP/Perl provides SOAP::GenericInputStream to handle these events, which simply produces an object graph of hash references. If you want something different, on a per type URI basis, you can register alternate handlers so you can produce different output. See SOAP::TypeMapper for details.

The handler needs to implement a set of methods, and these are outlined in SOAP::GenericInputStream along with descriptions of what the default behavior is (in other words, what SOAP::GenericInputStream does for each of these methods).

The benefit of this design is that it avoids using a DOM to parse SOAP packets; rather, the packet is unmarshaled directly into whatever final form you need. This is more efficient in space and time than first unmarshaling into a DOM and then traversing the DOM to create an object graph that is meaningful to your program. To get the full benefit of this, you may need to implement a handler that creates your custom object graph from the SOAP packet (see SOAP::GenericInputStream for details). Since SOAP::Parser does all the hard work, implementing a handler (or set of handlers) is really pretty painless.

new(TypeMapper)

Creates a new parser. Be sure *not* to reuse a parser for multiple SOAP packets - create one, use it, and then throw it away and get a new one if you need to parse a second SOAP packet.

TypeMapper is an optional parameter that points to an instance of SOAP::TypeMapper that allows you to register alternate serializers and deserializers for different classes of objects. See the docs for that class for more details. If you don't pass this parameter, the system uses a global TypeMapper object.

parsestring(String)

Parses the given string.

parsefile(Filename)

Parses the given file.

get_headers()

After parsing, this function returns the array of headers in the SOAP envelope.

Specifically, this function returns an array reference that contains zero or more hash references, each of which always take the following form:

  {
    soap_typeuri  => 'namespace qualification of header',
    soap_typename => 'unqualified name of header',
    content       => <header object>
  }

For instance, the following header:

 <f:MyHeader xmlns:f="urn:foo">42 </f:MyHeader>

would be deserialized in this form:

  {
    soap_typeuri  => 'urn:foo',
    soap_typename => 'MyHeader',
    content       => 42,
  }
 
while this header:
 <f:MyHeader xmlns:f="urn:foo">
  <m1>something</m1>
  <m2>something else</m2>
 </f:MyHeader>

would be deserialized (by default) in this form:

  {
    soap_typeuri  => 'urn:foo',
    soap_typename => 'MyHeader',
    content       => {
        soap_typeuri  => 'urn:foo',
        soap_typename => 'MyHeader',
        m1 => 'something',
        m2 => 'something else',
    },
  }

Note the redundancy of the soap_typeuri and soap_typename isn't strictly necessary in this case because this information is embedded in the content itself. However, because of the potential (and common need) for sending scalars as the entirety of the header content, we need some way of communicating the namespace and typename of the header. Thus the content, for consistency, is always packaged in a hash along with explicit type information.

get_body()

After parsing, this function retrieves the body of the SOAP envelope.

Since it doesn't make sense to send just a scalar as the body of a SOAP request, we don't need the redundancy of packaging the content inside of a hash along with its type and namespace (as was done above with headers). For instance:

 <f:MyBody xmlns:f="urn:foo">
  <m1>something</m1>
  <m2>something else</m2>
 </f:MyBody>

would be deserialized (by default) as the following:

 {
   soap_typeuri  => 'urn:foo',
   soap_typename => 'MyBody',
   m1 => 'something',
   m2 => 'something else',
 }

DEPENDENCIES

XML::Parser::Expat SOAP::GenericInputStream SOAP::Defs

AUTHOR

Keith Brown

SEE ALSO

SOAP::GenericInputStream