rpc-encoded SOAP messages
The SOAP nodes are configured using a specific WSDL binding
that has a style of either document
(the default)
or rpc
. All the operations defined within a particular
WSDL binding are usually defined with the same use, which can be either literal
(the
default) or encoded
.
SOAP messages that are rpc-encoded
can carry SOAP
encoding annotations that are designed to give the receiver additional
information about the message being sent. The following four types
of annotations are common:
- If the message flow builds outbound messages incorporating SOAP
arrays, use ESQL to add any required attributes, as follows:
arrayType
for SOAP 1.1arraySize
anditemType
for SOAP 1.2
- If the message flow receives messages using SOAP arrays, disable validation.
- If the message flow receives messages using multi-reference encoding,
disable validation and, if necessary, navigate the resulting logical
tree using the
href
(orref
) andid
attributes.
xsi:type
An xsi:type
attribute
can be added to an element to specify its type. For example:
<data xsi:type="xsd:string">text</data>
where
the namespace prefix xsi
is defined as follows:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
For
a web service built from WSDL and XML schema, the type information
is already available and the xsi:type
is redundant.
Generally,
when building an outbound message, you do not add xsi:type
information.
The following ESQL example shows how to add xsi:type
information
if it is required:
DECLARE xsd NAMESPACE 'http://www.w3.org/2001/XMLSchema';
DECLARE xsi NAMESPACE 'http://www.w3.org/2001/XMLSchema-instance';
SET OutputRoot.SOAP.Context.Namespace.(SOAP.NamespaceDecl)xmlns:xsd = xsd;
SET OutputRoot.SOAP.Context.Namespace.(SOAP.NamespaceDecl)xmlns:xsi = xsi;
SET OutputRoot.SOAP.Body.rpc:op1.part1.data.(SOAP.Attribute)xsi:type = 'xsd:string';
When
parsing an inbound message, any xsi:type
information
is added to the logical tree in the same way as other attributes,
as follows:
(0x03000000:PCDataField):data = 'text' (CHARACTER)
(
(0x03000100:Attribute)http://www.w3.org/2001/XMLSchema-instance:type = 'xsd:string' (CHARACTER)
)
encodingStyle
An encodingStyle
attribute
can be added to an element to specify the SOAP encoding style used.
For example:
<tns:op1 soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
where
the namespace prefix soapenv
is defined as the namespace
of your SOAP Envelope, as follows:
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" (SOAP 1.1)
xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" (SOAP 1.2)
The value itself is a list of URIs, but the values in common use are as follows:
"http://schemas.xmlsoap.org/soap/encoding/" (SOAP 1.1)
"http://www.w3.org/2003/05/soap-encoding" (SOAP 1.2)
In
SOAP 1.1, the encodingStyle
attribute can be added
to any element. In SOAP 1.2 the encodingStyle
attribute
can be added only to children of Body, Header and Detail.
Generally,
you build an outbound message, you do not add the encodingStyle
attribute.
The following ESQL example shows how to add encodingStyle
information,
if it is required:
DECLARE soapenv NAMESPACE 'http://schemas.xmlsoap.org/soap/envelope/';
DECLARE soapenc NAMESPACE 'http://schemas.xmlsoap.org/soap/encoding/';
SET OutputRoot.SOAP.Body.tns:op1.(SOAP.Attribute)soapenv:encodingStyle = soapenc;
When
parsing an inbound message, any encodingStyle
attributes
are added to the logical tree in the same way as other attributes,
as follows:
(0x03000100:Attribute)http://schemas.xmlsoap.org/soap/envelope/:encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/' (CHARACTER)
Arrays
A SOAP array is an element containing a sequence of child elements of the same type. In the following XML schema example, there is a type called data with two elements: a simple string and an array. In the schema, the field called array has an unspecified number of children of type string. The name of those child elements is not specified.
<xsd:complexType name="ArrayOfString">
<xsd:complexContent mixed="false">
<xsd:restriction base="soapenc:Array">
<xsd:attribute wsdl:arrayType="xsd:string[]" ref="soapenc:arrayType"/>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="data">
<xsd:sequence>
<xsd:element name="simple" type="xsd:string"/>
<xsd:element name="array" type="tns:ArrayOfString"/>
</xsd:sequence>
</xsd:complexType>
The namespaces used in the example are from WSDL 1.1 and SOAP 1.1, as follows:
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
The following example is part of a valid instance document matching the schema:
<array soapenc:arrayType="xsd:string[]">
<item>item1</item>
<item>item2</item>
</array>
When you build an outbound message, you
must add the appropriate attributes. For example, the following ESQL
shows how to add the arrayType
attribute:
DECLARE xsd NAMESPACE 'http://www.w3.org/2001/XMLSchema';
DECLARE soapenc NAMESPACE 'http://schemas.xmlsoap.org/soap/encoding/';
SET OutputRoot.SOAP.Context.Namespace.(SOAP.NamespaceDecl)xmlns:xsd = xsd;
SET OutputRoot.SOAP.Body.rpc:op1.p1.array.(SOAP.Attribute)soapenc:arrayType = 'xsd:string[]';
The
attributes used by SOAP 1.1 and SOAP 1.2 are different. SOAP 1.1 uses
the arrayType
attribute. The size of the array can
be specified, but is not required. SOAP 1.2 uses two separate attributes.
The equivalent SOAP 1.2 attributes for the previous example are soapenc:itemType="xsd:string"
and soapenc:arraySize="2"
,
where the namespace prefixes are defined as follows:
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc=" http://www.w3.org/2003/05/soap-encoding"
You must disable validation if your message flow receives SOAP encoded messages containing SOAP arrays. The instance document cannot be validated against the schema when parsing an inbound message, because the name of the array items is not defined by the schema.
Multi-reference
The
following example shows a SOAP 1.1 request message for a WSDL rpc-encoded
operation
called op1
:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soapenv:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:rpc="http://example/rpc">
<rpc:op1>
<p1>
<simple>text</simple>
<array soapenc:arrayType="xsd:string[]">
<Item>item1</Item>
<Item>item2</Item>
</array>
</p1>
</rpc:op1>
</soapenv:Body>
</soapenv:Envelope>
A SOAP implementation can reorganize this logical message to use multi-reference elements, as follows:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soapenv:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:rpc="http://example/rpc">
<rpc:op1>
<p1 href="#id1"/>
</rpc:op1>
<rpc:data id="id1">
<simple>text</simple>
<array href="#id2"/>
</rpc:data>
<soapenc:Array id="id2" soapenc:arrayType="xsd:string[]">
<Item>Array Element 0</Item>
<Item>Array Element 1</Item>
</soapenc:Array>
</soapenv:Body>
</soapenv:Envelope>
The message is logically equivalent
to the first example, but the children of elements p1
and array
have
been split out into separate sibling elements and then referenced
using the href
attribute.
The introduced elements,
such as <data>
:
- Can be referenced from more than one location, which allows the message to state that such elements are identical, as opposed to separate items which have the same value. The message size could be reduced if a shared element is large and referenced many times.
- Can directly or indirectly reference themselves, which allows the message to represent a graph that contains circular references.
Neither of these considerations applies to the previous example.
Generally, when you build an outbound message, you do not encode multi-reference elements unless the message represents a graph. Otherwise, the multi-reference encoding is optional. The following ESQL example shows how to encode multi-reference elements:
-- ESQL namespace prefixes
DECLARE soapenc NAMESPACE 'http://schemas.xmlsoap.org/soap/encoding/';
DECLARE xsd NAMESPACE 'http://www.w3.org/2001/XMLSchema';
DECLARE rpc NAMESPACE 'http://example/rpc';
-- define XML namespace prefixes
SET OutputRoot.SOAP.Context.Namespace.(SOAP.NamespaceDecl)xmlns:soapenc = soapenc;
SET OutputRoot.SOAP.Context.Namespace.(SOAP.NamespaceDecl)xmlns:xsd = xsd;
SET OutputRoot.SOAP.Context.Namespace.(SOAP.NamespaceDecl)xmlns:rpc = rpc;
-- build request message
SET OutputRoot.SOAP.Body.rpc:op1.p1.(SOAP.Attribute)href = '#id1';
SET OutputRoot.SOAP.Body.rpc:data.(SOAP.Attribute)id = 'id1';
SET OutputRoot.SOAP.Body.rpc:data.simple = 'text';
SET OutputRoot.SOAP.Body.rpc:data.array.(SOAP.Attribute)href = '#id2';
SET OutputRoot.SOAP.Body.soapenc:Array.(SOAP.Attribute)id = 'id2';
SET OutputRoot.SOAP.Body.soapenc:Array.(SOAP.Attribute)soapenc:arrayType = 'xsd:string[]';
SET OutputRoot.SOAP.Body.soapenc:Array.Item[1] = 'item1';
SET OutputRoot.SOAP.Body.soapenc:Array.Item[2] = 'item2';
When parsing an inbound message, multi-reference elements do not match the XML schema from the web service WSDL. If validation is enabled on a SOAP node, then an exception is thrown. If you use multi-reference encoding, then you must disable validation.
When you have a logical tree built from the message, you can propagate this tree to another SOAP node for output. For example, with a façade flow as shown in the following diagram, if the SOAPRequest node receives a response using multi-reference encoding, you can propagate the logical tree for the response to the SOAPReply node, and a SOAP message with multi-reference encoding is returned to the original client.
The original client must also understand the multi-reference encoding.
To manipulate
the logical tree for a multi-reference encoded message, navigate the href
and id
attributes
in ESQL. These attributes are slightly different in SOAP 1.1 and SOAP
1.2, as follows:
- In SOAP 1.1, the referencing element has an attribute
href="#id"
and the item referencedid="id"
. - In SOAP 1.2, the referencing element has an attribute
ref="id"
and the item referencedid="id"
.