The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
=head1 NAME

XML::Compile::SOAP11::Encoding - SOAP encoding

=head1 SYNOPSIS

 ### FOR THE MOMENT UNUSABLE
 # see t/13enc11.t in the distribution for complex examples

 my $client = XML::Compile::SOAP11::Client->new();
 $client->startEncoding(...);  # loads this module

 # create: <SOAP-ENC:int>41</SOAP-ENC:int>
 my $xml = $client->enc(int => 41);

 # create: <SOAP-ENC:int id="hhtg">42</SOAP-ENC:int>
 my $xml = $client->enc(int => 42, 'hhtg');

 # create: <code xsi:type="xsd:int">43</code>
 my $int = pack_type SCHEMA2001, 'int';
 my $xml = $client->typed($int, code => 43);

 # create: <ref href="#id-1"/>  (xyz get's id if it hasn't)
 my $xml = $client->href('ref', $xyz);
 my $xml = $client->href('ref', $xyz, 'id-1');  # explicit label
 
 # create: <number>3</number>   (gets validated as well!)
 my $xml = $client->element($int, number => 3);

 # create one-dimensional array of ints
 my $xml = $client->array(undef, $int, \@xml);
 my $xml = $client->array('{myns}mylocal', $int, \@xml);

 # create multi-dimensional array
 my $xml = $client->multidim(undef, $int, $matrix);
 my $xml = $client->multidim('{myns}mylocal', $int, $matrix);

 # decode an incoming encoded structure (as far as possible)
 my $hash = $client->dec($xml);

=head1 DESCRIPTION

This module loads extra functionality into the L<XML::Compile::SOAP|XML::Compile::SOAP>
namespace: all kinds of methods which are used to SOAP-encode data.

The loading is triggered by calling L<startEncoding()|XML::Compile::SOAP11::Encoding/"Encoding">.  In threaded
applications, you may wish to call that method once before the fork(),
such that not each threads or forked process needs to compile the
code again.  Of course, you can also C<use> this package explicitly.

=head1 METHODS

=head2 Transcoding

SOAP defines encodings, especially for SOAP-RPC.

=head3 Encoding

=over 4

=item $obj-E<gt>B<array>((NAME|undef), ITEM_TYPE, ARRAY-of-ELEMENTS, OPTIONS)

Arrays can be a mess: a mixture of anything and nothing.  Therefore,
you have to help the generation more than you may wish for.  This
method produces an one dimensional array, L<multidim()|XML::Compile::SOAP11::Encoding/"Encoding"> is used for
multi-dimensional arrays.

The NAME is the packed type of the array itself.  When undef,
the C<< {soap-enc-ns}Array >> will be used (the action soap
encoding namespace will be used).

The ITEM_TYPE specifies the type of each element within the array.
This type is used to create the C<arrayType> attribute, however
doesn't tell enough about the items themselves: they may be
extensions to that type.

Each of the ELEMENTS must be an XML::LibXML::Node, either
self-constructed, or produced by one of the builder methods in
this class, like L<enc()|XML::Compile::SOAP11::Encoding/"Encoding"> or L<typed()|XML::Compile::SOAP11::Encoding/"Encoding">.

Returned is the XML::LibXML::Element which represents the
array.

 -Option      --Default
  array_type    <generated>
  id            <undef>
  nested_array  ''
  offset        0
  slice         <all remaining>

=over 2

=item array_type => STRING

The arrayType attribute content.  When explicitly set to undef, the
attribute is not created.

=item id => STRING

Assign an id to the array.  If not defined, than no id attribute is
added.

=item nested_array => STRING

The ARRAY type should reflect nested array structures if they are
homogeneous.  This is a really silly part of the specs, because there
is no need for it on any other comparible place in the specs... but ala.

For instance: C<< nested_array => '[,]' >>, means that this array
contains two-dimensional arrays.

=item offset => INTEGER

When a partial array is to be transmitted, the number of the base
element.

=item slice => INTEGER

When a partial array is to be transmitted, this is the length of
the slice to be sent (the number of elements starting with the C<offset>
element)

=back

=item $obj-E<gt>B<element>(TYPE, NAME, VALUE)

Create an element.  The NAME is for node, where a namespace component
is translated into a prefix.  When you wish for a C<type> attribute,
use L<typed()|XML::Compile::SOAP11::Encoding/"Encoding">.

When the TYPE does not contain a namespace indication, it is taken
in the selected schema namespace.  If the VALUE already is a
XML::LibXML::Element, then that one is used (and the NAME ignored).

=item $obj-E<gt>B<enc>(LOCAL, VALUE, [ID])

In the SOAP specification, encoding types are defined: elements
which do not have a distinguishable name but use the type of the
data as name.  Yep, ugly!

example: 

  my $xml = $soap->enc('int', 43);
  my $xml = $soap->enc(int => 43);
  print $xml->toString;
    # <SOAP-ENC:int>43</SOAP-ENC:int>

  my $xml = $soap->enc('int', 42, id => 'me');
  my $xml = $soap->enc(int => 42, id => 'me');
  print $xml->toString;
    # <SOAP-ENC:int id="me">42</SOAP-ENC:int>

=item $obj-E<gt>B<encAddNamespace>(PAIRS)

Convenience alternative for L<encAddNamespaces()|XML::Compile::SOAP11::Encoding/"Encoding">.

=item $obj-E<gt>B<encAddNamespaces>(PAIRS)

Add prefix definitions for this one encoding cyclus.  Each time
L<startEncoding()|XML::Compile::SOAP11::Encoding/"Encoding"> is called, the table is reset.  The namespace
table is returned.

=item $obj-E<gt>B<href>(NAME, ELEMENT, [ID])

Create a reference element with NAME to the existing ELEMENT.  When the
ELEMENT does not have an "id" attribute yet, then ID will be used.  In
case not ID was specified, then one is generated.

=item $obj-E<gt>B<multidim>((NAME|undef), ITEM_TYPE, ARRAY-of-ELEMENTS, OPTIONS)

A multi-dimensional array, less flexible than a single dimensional
array, which can be created with L<array()|XML::Compile::SOAP11::Encoding/"Encoding">.

The array must be square: in each of the dimensions, the length of
each row must be the same.  On the other hand, it may be sparse
(contain undefs).  The size of each dimension is determined by the
length of its first element.

 -Option--Default
  id      undef

=over 2

=item id => STRING

=back

=item $obj-E<gt>B<nil>([TYPE], NAME)

Create an element with NAME which explicitly has the C<xsi:nil> attribute.
If the NAME is full (has a namespace to it), it will be translated into
a QNAME, otherwise, it is considered not namespace qualified.

If a TYPE is given, then an explicit type parameter is added.

=item $obj-E<gt>B<prefixed>(TYPE|(NAMESPACE,LOCAL))

Translate a NAMESPACE-LOCAL combination (which may be represented as
a packed TYPE) into a prefixed notation.

The complication is that the NAMESPACE may not naturally have a prefixed
assigned to it: the produced SOAP message is the result of compilation,
and only the namespaces which are registered to be used during compile-time
are added to the list on the top-level.

=item $obj-E<gt>B<startEncoding>(OPTIONS)

This needs to be called before any encoding routine, because it
initializes the internals.  Each call will reset all compiled
cached translator routines.

When you use the standard RPC-encoded interface, this will be
called for you.

 -Option    --Default
  doc         <required>
  namespaces  {}
  prefixes    {}

=over 2

=item doc => XML::LibXML::Document

=item namespaces => HASH|ARRAY

Pre release 0.74 name for option C<prefixes>.

=item prefixes => HASH|ARRAY

Like L<XML::Compile::Schema::compile(prefixes)|XML::Compile::Schema/"Compilers">, this can
be a HASH (see example) or an ARRAY with prefix-uri pairs.

=back

example: 

 my %ns;
 $ns{$MYNS} = {uri => $MYNS, prefix => 'm'};
 $soap->startEncoding(doc => $doc, prefixes => \%ns);

 # or
 $soap->startEncoding(doc => $doc, prefixes => [ m => $MYNS ]);

=item $obj-E<gt>B<struct>(TYPE, CHILDS)

Create a structure, an element with childs.  The CHILDS must be fully
prepared XML::LibXML::Element objects.

=item $obj-E<gt>B<typed>(TYPE, NAME, VALUE)

A "typed" element shows its type explicitly, via the "xsi:type" attribute.
The VALUE will get processed via an auto-generated XML::Compile writer,
so validated.  The processing is cashed.

When VALUE already is an XML::LibXML::Element, then no processing
nor value checking will be performed.  The NAME will be ignored.

If the TYPE is not qualified, then it is interpreted as basic type, as
defined by the selected schema.  If you explicitly
need a non-namespace typed item, then use an empty namespace.  In any
case, the type must be defined and the value is validated.

example: 

 my $xml = $soap->typed(int => count => 5);
 my $xml = $soap->typed(pack_type(SCHEMA1999, 'int'), count => 5);

 my $xml = $soap->typed(pack_type('', 'mine'), a => 1);
 my $xml = $soap->typed('{}mine'), a => 1); #same

=back

=head3 Decoding

=over 4

=item $obj-E<gt>B<dec>(XMLNODES)

Decode the XMLNODES (list of XML::LibXML::Element objects).  Use
Data::Dumper to figure-out what the produced output is: it is a guess,
so may not be perfect (do not use RPC but document style soap for
good results).

The decoded data is returned.  When L<startDecoding(simplify)|XML::Compile::SOAP11::Encoding/"Decoding"> is true,
then the returned data is compact but may be sloppy.  Otherwise,
a HASH is returned containing as much info as could be extracted from
the tree.

=item $obj-E<gt>B<decSimplify>(TREE, OPTIONS)

Simplify the TREE of output produced by L<dec()|XML::Compile::SOAP11::Encoding/"Decoding"> to contain only
data.  Of course, this will remove useful information.

From each of the HASHes in the tree, the C<_NAME>, C<_TYPE>, C<id>,
and any/anyAttribute fields are removed.  If only a C<_> is left over,
that related value will replace the HASH as a whole.

=item $obj-E<gt>B<startDecoding>(OPTIONS)

Each call to this method will restart the cache of the decoding
internals.

Currently B<not supported>, is the automatic decoding of elements which
I<inherit> from C<SOAP-ENC:Array>.  If you encounter these, you have to
play with hooks.

 -Option     --Default
  reader_opts  {}
  simplify     <false>

=over 2

=item reader_opts => HASH

Extend or overrule the default reader options.  Available options
are shown in L<XML::Compile::Schema::compile()|XML::Compile::Schema/"Compilers">.

=item simplify => BOOLEAN

Call L<decSimplify()|XML::Compile::SOAP11::Encoding/"Decoding"> automatically at the end of L<dec()|XML::Compile::SOAP11::Encoding/"Decoding">, so producing
an easily accessible output tree.

=back

=back

=head1 SEE ALSO

This module is part of XML-Compile-SOAP distribution version 2.34,
built on December 21, 2012. Website: F<http://perl.overmeer.net/xml-compile/>

Other distributions in this suite:
L<XML::Compile>,
L<XML::Compile::SOAP>,
L<XML::Compile::SOAP12>,
L<XML::Compile::SOAP::Daemon>,
L<XML::Compile::SOAP::WSA>,
L<XML::Compile::C14N>,
L<XML::Compile::WSS>,
L<XML::Compile::WSS::Signature>,
L<XML::Compile::Tester>,
L<XML::Compile::Cache>,
L<XML::Compile::Dumper>,
L<XML::Compile::RPC>,
L<XML::Rewrite>,
L<XML::eXistDB>,
and
L<XML::LibXML::Simple>.

Please post questions or ideas to the mailinglist at
F<http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/xml-compile>

For live contact with other developers, visit the C<#xml-compile> channel
on C<irc.perl.org>.

=head1 LICENSE

Copyrights 2007-2012 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 F<http://www.perl.com/perl/misc/Artistic.html>