| XML-Compile-SOAP documentation | view source | Contained in the XML-Compile-SOAP distribution. |
XML::Compile::SOAP - base-class for SOAP implementations
XML::Compile::SOAP is extended by XML::Compile::SOAP10 XML::Compile::SOAP11 XML::Compile::SOAP12
** SOAP1.1 and WSDL1.1 over HTTP
# !!! The next steps are only required when you do not have
# !!! a WSDL. See XML::Compile::WSDL11 if you have a WSDL.
# !!! Without WSDL file, you need to do a lot manually
use XML::Compile::SOAP11::Client;
my $client = XML::Compile::SOAP11::Client->new;
$client->schemas->importDefinitions(...);
use XML::Compile::Util qw/pack_type/;
my $h1el = pack_type $myns, $some_element;
my $b1el = "{$myns}$other_element"; # same, less clean
my $encode_query = $client->compileMessage
( 'SENDER'
, style => 'document' # default
, header => [ h1 => $h1el ]
, body => [ b1 => $b1el ]
, destination => [ h1 => 'NEXT' ]
, mustUnderstand => 'h1'
);
my $decode_response = $client->compileMessage
( 'RECEIVER'
, header => [ h2 => $h2el ]
, body => [ b2 => $b2el ]
, faults => [ ... ]
);
my $http = XML::Compile::Transport::SOAPHTTP
->new(address => $server);
my $http = $transport->compileClient(action => ...);
my @query = (h1 => ..., b1 => ...);
my $request = $encode_query->(@query);
my ($response, $trace) = $http->($request);
my $answer = $decode_response->($response);
use Data::Dumper;
warn Dumper $answer; # discover a HASH with h2 and b2!
if($answer->{Fault}) ... # when an error was reported
# Simplify your life: combine above into one call
# Also in this case: if you have a WSDL, this is created
# for you. $wsdl->compileClient('MyFirstCall');
my $call = $client->compileClient
( kind => 'request-response' # default
, name => 'MyFirstCall'
, encode => $encode_query
, decode => $decode_response
, transport => $http
);
# !!! Usage, with or without WSDL file the same
my $result = $call->(@quey) # SCALAR only the result
print $result->{h2}->{...};
print $result->{b2}->{...};
my ($result, $trace) = $call->(...); # LIST will show trace
# $trace is an XML::Compile::SOAP::Trace object
This module handles the SOAP protocol. The first implementation is SOAP1.1 (http://www.w3.org/TR/2000/NOTE-SOAP-20000508/), which is still most often used. The SOAP1.2 definition (http://www.w3.org/TR/soap12/) is quite different; this module tries to define a sufficiently abstract interface to hide the protocol differences.
Be aware that there are three kinds of SOAP:
Document style (literal) SOAP, where there is a WSDL file which explicitly types all out-going and incoming messages. Very easy to use.
RPC style SOAP literal. The body of the message has an extra element wrapper, but the content is also well defined.
RPC style SOAP encoded. The sent data is nowhere described formally. The data is constructed in some ad-hoc way.
Don't forget to have a look at the examples in the examples/ directory included in the distribution.
Create a new SOAP object. You have to instantiate either the SOAP11 or SOAP12 sub-class of this, because there are quite some differences (which can be hidden for you)
-Option --Default media_type application/soap+xml schemas created internally
XML::Compile::Cache objectUse this when you have already processed some schema definitions. Otherwise,
you can add schemas later with $soap->schemas->importDefinitions()
The Cache object must have any_element and any_attribute set to
'ATTEMPT'
Returns the XML::Compile::Cache object which contains the knowledge about the types.
The payload is defined explicitly, where all headers and bodies are described in detail. When you have a WSDL file, these ENTRIES are generated automatically, but can be modified and extended (WSDL files are often incomplete)
To make your life easy, the ENTRIES use a label (a free to choose key,
the part name in WSDL terminology), to ease relation of your data with
the type where it belongs to. The element of an entry (the value) is
defined as an any element in the schema, and therefore you will need
to explicitly specify the element to be processed.
As OPTIONS, you can specify any listed here, but also anything which is
accepted by XML::Compile::Schema::compile(), like
sloppy_integers => 1 and hooks. These are applied to all header
and body elements (not to the SOAP wrappers)
-Option --Default body [] destination [] faults [] header undef mustUnderstand [] role ULTIMATE roles []
ARRAY of PAIRS, defining a nice LABEL (free of choice but unique, also w.r.t. the header and fault ENTRIES) and an element type name or CODE reference. The LABEL will appear in the Perl HASH only, to be able to refer to a body element in a simple way.
Writers only. Indicate who the target of the header entry is. By default, the end-point is the destination of each header element.
The ARRAY contains a LIST of key-value pairs, specifing an entry label followed by an actor (soap1.1) or role (soap1.2) URI. You may use the predefined actors/roles, like 'NEXT'. See roleURI() and roleAbbreviation().
The SOAP1.1 and SOAP1.2 protocols define fault entries in the answer. Both have a location to add your own additional information: the type(-processor) is to specified here, but the returned information structure is larger and differs per SOAP implementation.
ARRAY of PAIRS, defining a nice LABEL (free of choice but unique) and an element type name. The LABEL will appear in the Perl HASH, to refer to the element in a simple way.
The element type is used to construct a reader or writer. You may also create your own reader or writer, and then pass a compatible CODE reference.
Writers only. The specified header entry labels specify which elements
must be understood by the destination. These elements will get the
mustUnderstand attribute set to 1 (soap1.1) or true (soap1.2).
Readers only.
One or more URIs, specifying the role(s) you application has in the
process. Only when your role contains ULTIMATE, the body is
parsed. Otherwise, the body is returned as uninterpreted XML tree.
You should not use the role NEXT, because every intermediate
node is a NEXT.
All understood headers are parsed when the actor (soap1.1) or
role (soap1.2) attribute address the specified URI. When other
headers emerge which are not understood but carry the mustUnderstood
attribute, an fault is returned automatically. In that case, the
call to the compiled subroutine will return undef.
Alternative for option role
Returns a HASH with some collected information from a complete SOAP
message (XML::LibXML::Document or XML::LibXML::Element). Currenty,
the HASH contains a header and a body key, with each an ARRAY
of element names which where found in the header resp. body.
Produce an error structure to be returned to the sender.
Translate a role URI into a simple string, if predefined. See roleURI().
Translates actor/role/destination abbreviations into URIs. Various SOAP protocol versions have different pre-defined STRINGs, which can be abbreviated for readibility. Returns the unmodified URI in all other cases.
SOAP11 only defines NEXT. SOAP12 defines NEXT, NONE, and
ULTIMATE.
Although the specifications of SOAP1.1 and WSDL1.1 are thin, the number of special constructs are many. And, of course, all are poorly documented. Both SOAP and WSDL have 1.2 versions, which will clear things up a lot, but are not used that often yet.
WSDL defines two kinds of messages: document style SOAP and rpc
style SOAP. In document style SOAP, the messages are described in
great detail in the WSDL: the message components are all defined in
Schema's. The worst things you can (will) encounter are any schema
elements which require additional manual processing.
RPC Literal behaves very much the same way as document style soap,
but has one extra wrapper inside the Body of the message.
Encoded SOAP-RPC, however, is a very different ball-game. It is simple
to use with strongly typed languages, to exchange data when you create both
the client software and the server software. You can simply autogenerate
the data encoding. Clients written by third parties have to find the
documentation on how to use the encoded RPC call in some other way... in
text, if they are lucky; the WSDL file does not contain the prototype
of the procedures, but that doesn't mean that they are free-format.
Encoded RPC messsages are shaped to the procedures which are being called on the server. The body of the sent message contains the ordered list of parameters to be passed as 'in' and 'in/out' values to the remote procedure. The body of the returned message lists the result value of the procedure, followed by the ordered 'out' and 'in/out' parameters.
XML uses namespaces: URIs which are used as constants, grouping a set of type and element definitions. By using name-spaces, you can avoid name clashes, which have frustrated many projects in the past when they grew over a certain size... at a certain size, it becomes too hard to think of good distinguishable names. In such case, you must be happy when you can place those names in a context, and use the same naming in seperate contexts without confusion.
That being said: XML supports both namespace- and non-namespace elements
and schema's; and of cause many mixed cases. It is by far preferred to
use namespace schemas only. In a schema XSD file, look for the
targetNamespace attribute of the schema element: if present, it
uses namespaces.
In XML data, it is seen as a hassle to write the full length of the URI each time that a namespace is addressed. For this reason, prefixes are used as abbreviations for the namespace URI. In programs, you can simply assign short variable names to long URIs, so we do not need that trick.
Within your program, you use
$MYSN = 'long URI of namespace';
... $type => "{$MYNS}typename" ...
or nicer
use XML::Compile::Util qw/pack_type/; use constant MYNS => 'some uri'; ... $type => pack_type(MYNS, 'typename') ...
The XML::Compile::Util module provides a helpful methods and constants, as does the XML::Compile::SOAP::Util.
To learn how to create clients in SOAP, read the DETAILS section in XML::Compile::SOAP::Client. The client implementation is platform independent.
Servers can be created with the external XML::Compile::SOAP::Daemon distribution. Those servers are based on Net::Server. Can be used to create a test-server in a few minutes... or production server.
Don't forget to have a look at the examples in the examples/ directory included in the distribution.
Start reading about wildcards in XML::Compile. When you receive a message which contains "ANY" elements, an attempt will be made to decode it automatically. Sending messages which contain "ANY" fields is harder... you may try hooks or something more along these lines:
my $doc = XML::LibXML::Document->new('1.0', 'UTF-8');
my $type = pack_type $ns, $local;
my $node = $wsdl->writer($type)->($doc, $value);
my $message = { ..., $type => $node };
my $call = $wsdl->compileClient('myOpToCall');
my ($answer, $trace) = $call->(_doc => $doc, message => $message);
Here, $type is the type of the element which needs to be filled in
on a spot where the schema defines an "ANY" element. You need to include
the full typename as key in the HASH (on the right spot) and a fully
prepared $node, an XML::LibXML::Element, as the value.
You see that the $doc which is created to produce the special node
in the message is also passed to the $call. The call produces the
message which is sent and needs to use the same document object as the
node inside it. The chances are that when you forget to pass the $doc
it still works... but you may get into characterset problems and such.
This module is part of XML-Compile-SOAP distribution version 2.24, built on June 20, 2011. Website: http://perl.overmeer.net/xml-compile/
Other distributions in this suite: XML::Compile, XML::Compile::SOAP, XML::Compile::SOAP12, XML::Compile::SOAP::Daemon, XML::Compile::SOAP::WSA, XML::Compile::C14N, XML::Compile::WSS, XML::Compile::Tester, XML::Compile::Cache, XML::Compile::Dumper, XML::Compile::RPC, XML::Rewrite, XML::eXistDB, and XML::LibXML::Simple.
Please post questions or ideas to the mailinglist at
http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/xml-compile
For live contact with other developers, visit the #xml-compile channel
on irc.perl.org.
Copyrights 2007-2011 by Mark Overmeer. For other contributors see ChangeLog.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html
| XML-Compile-SOAP documentation | view source | Contained in the XML-Compile-SOAP distribution. |