- Understanding SOAP
- SOAP Basics
- Messaging Framework
- The SOAP Encoding
- Transport Options
- Summary
The SOAP Encoding
The specification goes on at great length over the encoding. In this article, we can point out only the most important rules; turn to the specification itself if you need more details.
CAUTION
Unlike traditional middleware, SOAP does not explicitly map its encoding to programming languages. In other words, there is no standard SOAP mapping for Java. Therefore, two different implementations of SOAP may produce different encoding for the same objects.
Encoding Fields
The most basic rule is that values are always encoded in elements. For example, a name field is encoded as:
<name>Board room</name>
but not as:
<item name="Board room"/>
SOAP uses attributes exclusively to modify the default processing of an element. For example, the env:actor attribute indicates which node should process the element.
Simple Types
SOAP supports the simple types defined in the XML schema, Part 2: Datatypes recommendation (http://www.w3.org/TR/2001/REC-xmlschema-2-20010502). The most commonly used types are as follows:
string
base64Binary
integer, byte, short, int, long
decimal, float, double
boolean
dateTime, time, date, duration
Note that base64Binary supports binary objects.
CAUTION
SOAP 1.1 uses an earlier draft of XML schema that is identified with the http://www.w3.org/1999/XMLSchema-instance namespace URI.
Simple types are encoded as XML elements. If required, the xsi:type attribute may disambiguate the type. For example, a date might be encoded as:
<start xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="xsd:dateTime">2001-01-15T00:00:00Z</start>
SOAP states that the xsi:type must be used when the type of the element cannot be deduced from its name. In practice, this is a major source of interoperability problems between SOAP implementations.
Indeed, different programming languages have different needs for the use of xsi:type. For example, Java is strongly typed and Java implementations use the xsi:type attribute liberally. Languages with less restrictive type systems may ignore the xsi:type attribute, which leads to conflicts.
Note that using valid XML documents (that is, documents with an XML schema) may help reduce ambiguities. However, as of this writing, no SOAP implementation uses schemas.
Compound Types: Structs
The encoding recognizes two compound types:
A structure (struct) is a list of elements logically grouped together. The elements are identified by their names. (The element accessor is its name.)
The array is a group of values identified not by their names but by their ordinal positions. (The accessor of the element is the position of the element in the array.)
Structures are encoded as accessor elements. (In most cases, the element borrows its name from the name of the struct in the programming language.) The fields are encoded as accessor elements. Having accessors whose names are local to their containing types results in unqualified elements; other elements are always qualified with a namespace.
You already saw how to encode a structure in Listing 8 (reproduced here for your convenience):
<?xml version="1.0"?> <rs:Resource xmlns:rs="http://www.psol.com/2001/resourceful" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <id xsi:type="xsd:int">0</id> <name xsi:type="xsd:string">Auditorium</name> <description xsi:type="xsd:string">Our largest meeting room </description> </rs:Resource>
Compound Type: Arrays
Arrays are encoded as elements of type enc:Array (or a type derived from enc:Array) where enc is bound to http://schemas.xmlsoap.org/soap/encoding/ or http://www.w3.org/2001/09/soap-encoding, respectively, for SOAP 1.1 and SOAP 1.2.
The array element has an additional attribute, enc:arrayType, which declares the content of the array. Array type declarations are of the form
type[size]
This is very close to Java. A array of three strings has an enc:arrayType value of xsd:string[3]; an array with 25 integers has an enc:arrayType value of xsd:integer[25]. A multi-dimensional array is of the form xsd:decimal[5][10].
The array content is encoded as a sequence of XML elements. The names of the elements are irrelevant because, for arrays, the position of the element is the accessor. Listing 11 is an array of strings.
Listing 11An Array of Strings
<array xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="enc:Array" enc:arrayType="xsd:String[3]"> <item xsi:type="xsd:string">Board room</item> <item xsi:type="xsd:string">Meeting room 1</item> <item xsi:type="xsd:string">Meeting room 2</item> </array>
For obvious reasons, the elements must appear in the order of the array.
Array elements are not limited to simple types; compound types are acceptable, as Listing 12, an array of Resource objects, illustrates. The Resource class was defined in Listing
Listing 12An Array of Compound Types
<array xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="enc:Array" enc:arrayType="rs:Resource[3]" xmlns:rs="http://www.psol.com/2001/resourceful" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> <item xsi:type="rs:Resource"> <id xsi:type="xsd:int">1</id> <name xsi:type="xsd:string">Board room</name> <description xsi:type="xsd:string">Mid-sized room, quality furniture</description> </item> <item xsi:type="rs:Resource"> <id xsi:type="xsd:int">2</id> <name xsi:type="xsd:string">Meeting room 1</name> <description xsi:type="xsd:string">Mid-sized room</description> </item> <item xsi:type="rs:Resource"> <id xsi:type="xsd:int">3</id> <name xsi:type="xsd:string">Meeting room 2</name> <description xsi:type="xsd:string">Small room</description> </item> </array>
To support multidimensional arrays, SOAP uses references to arrays. A reference is an href attribute. An href attribute is a URI that points to another element in the same document. The original element is identified with an id attribute. The id attribute is of type ID as defined in XML schema and DTD.
The multidimensional array is encoded as an array of reference items pointing to the actual column data. In other words, a multidimensional array is an array whose elements point to other arrays.
Listing 13 is a multidimensional array. Note that this is a document fragment because it does not have a root element. In practice, with SOAP, it is never a problem to use document fragments since env:Envelope is the root.
Listing 13A multidimensional array
<matrix xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:enc="http://www.w3.org/2001/09/soap-encoding" xsi:type="enc:Array" enc:arrayType="xsd:int[][2]" > <item href="#array-1"/> <item href="#array-2"/> </matrix> <array xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:enc="http://www.w3.org/2001/09/soap-encoding" id="array-1" enc:arrayType="xsd:int[3]"> <item>10</item> <item>20</item> <item>30</item> </array> <array xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:enc="http://www.w3.org/2001/09/soap-encoding" id="array-2" enc:arrayType="xsd:int[2]"> <item>15</item> <item>25</item></array>
Because arrays can grow very large, the encoding has two optimizations for partially transmitted arrays and sparse arrays. In a partially transmitted array, not every element is sent. Typically it would be used when the recipient knows some sections of the array. The env:offset attribute specifies the zero-origin offset of the elements being transmitted in the array:
<enc:Array enc:arrayType="xsd:int[7]" enc:offset="[3]" xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> <item>4</item> <item>5</item> <item>6</item> </enc:Array>Likewise, the enc:position encodes sparse arrays, in other words, arrays where most elements are null or not present:
<enc:Array enc:arrayType="xsd:string[10,10]" xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> <item enc:position="[2,2]">Third row, third col</item> <item enc:position="[7,2]">Eighth row, third col</item> </enc:Array>