Independent elements
In soap, a stand-alone element represents an instance of a type that is referenced by at least one multiple-reference access element. All independent elements are marked with the Soap:id attribute, and the value of this property must be unique throughout the SOAP envelope. Independent elements are encoded as if they were packaged by an access element, and the tag name of the access element is the type name of the name domain limit for the instance. In the example above, the name domain limit for an instance is t:adjustment.
Soap restricts the places where independent elements can be encoded. Soap defines an attribute that can be applied to any element: (soap:package). This property is used to control where independent elements can be decoded. SOAP serialization rules indicate that a stand-alone element must be encoded as a direct child element of a soap:header element or soap:body element, or any other element labeled soap:package= ' true '. By annotating an element as a package, you can guarantee that the XML element that encodes that instance is fully self-contained and that there are no more than one reference access element referenced to that element outside of the package.
Suppose the transfer class corresponds to a method request. If the transfer type is not a package, the independent elements referenced by the to and from Access elements will appear as direct child elements of the soap:body element, as shown in Figure 10. If the transfer type is a legitimate SOAP packet type, the encoding may look like the one shown in Figure 11. Note that because the transfer element is a package, all the multiple-reference accessor elements refer to the contained elements. This makes it easier to think of the transfer element as a separate piece of XML code that can be separated from its parent element.
There is an exception to the model where multiple reference access elements always refer to independent elements. SOAP allows access elements that contain string and binary data to be the target of multiple-referencing access elements. This means that the following code is legal:
hello, soap
Although the fact is that Access element 2 has a Soap:id attribute, it is actually an access element rather than an independent element.
SOAP arrays
An array is encoded as a special example of a combination type. In soap, an array must have a rank (number of dimensions) and a capacity. An array is encoded as a combination type, in which each element is encoded as a child element whose name is the type name of the element's name domain limit.
Suppose you have the following COM IDL type definition:
struct Pointlist {
Long Celems;
[Size_is (Celems)] Point points[];
};
Instances of this type will be serialized as:
3
lt;x>3 lt;y>4 lt;/point>
lt;x>7 lt;y>5 lt;/point>
lt;x>1 lt;y>9 lt;/point>
If the points field is marked as a [ptr] attribute, this encoding will access the element with a multiple reference, as follows:
3
lt;x>3 lt;y>4 lt;/point>
lt;x>7 lt;y>5 lt;/point>
lt;x>1 lt;y>9 lt;/point>
When an array is encoded as an independent element, the tag name is the type name with the prefix arrayof.
Like NDRs and CDR, SOAP supports a partially converted array. If the number of child elements is less than the declared capacity, these elements are assumed to be missing from the end of the array. This can be ignored by using the Soap:offset property on the array element that is being included.
Soap:offset= ' [1] '
lt;x>1 lt;y>9 lt;/point>
The Soap:offset property represents the index of the first element that appears in the array. In the above example, the element 0,2 to 4 is not converted. SOAP also supports sparse arrays, which are implemented by using the Soap:position property to annotate each element with its absolute index:
lt;x>3 lt;y>4 lt;/point>
lt;x>4 lt;y>5 lt;/point>
In this example, elements 0 through 2, 4 to 6, and 8 to 9 are not converted.
Note that the exact syntax of arrays in soap is also being re-examined in the writing of this article to adjust to the upcoming XML schema specification for the consortium. Keep abreast of the latest version of the SOAP specification for more details.
Error handling
A server will sometimes not be able to properly service a method request. This may be caused by a general HTTP error (such as a request-uri cannot be mapped to a local resource or a security violation at an HTTP level). It may also be a problem in the SOAP translation software, such as a Marshall packing error or a required head that cannot be recognized. Other possible causes include a request that is not properly serviced, or that the application/object code decides to return an application-level error to the caller. These situations are clearly dealt with in the SOAP specification.
If an error occurs at the HTTP layer before the call to any SOAP code is distributed, a pure HTTP response must be returned. The standard HTTP status code number will be adopted, the level 400 code represents a client-raised error, and level 500 code represents an error caused by the server. This is usually handled automatically by the Web server software before the code executes.
Assuming that everything is OK at the HTTP layer, the next place where the error occurs is in those soap calls that translate and distribute to the application code (such as COM objects and CORBA servo objects). If the error occurs at this level, the server must return an error message instead of a standard response message. An error message is an instance of the following type of the root element encoded as soap:body.
Targetnamespace= ' Urn:schemas-xmlsoap-org:soap.v1 '
>
The FaultCode access element must contain a SOAP error code that is represented by a known integer or a value that is specifically applied to the name domain limit. The current SOAP error code is shown in Figure 12. The faultstring access element contains a description of the readability of the error that occurred. The RunCode accessor element contains a string whose value must be yes, no or Maybe, indicating whether the requested operation is actually executed before the error is generated. The detail access element is optional and is used to contain a specially applied exception object.
Here is an example of a SOAP error that corresponds to a request that contains an unrecognized required header element:
xmlns:soap= ' Urn:schemas-xmlsoap-org:soap.v1 '
>
;
$
Unrecognized ' causality ' header
No
Assuming that the specific application error needs to be returned, you may see the code shown in Figure 13. In the case of applying the defined error, the detail access element acts as a soap:body element when considering the application of the exception/Error object.
Mystery
A legacy HTTP issue needs further clarification. The HTTP Extension Framework convention is supported by soap (but not required) to specify the required HTTP header extensions. These conventions have two main purposes. First, they allow any URI to be used to qualify the range of a given HTTP header (like an XML Name field). Second, these conventions allow for separating the necessary headers from the optional headers (like Soap:mustunderstand). Here is an HTTP extension framework to define the Soapmethodname header as a necessary header extension:
M-post/foobar http/1.1
host:209.110.197.2
Man: "URN:SCHEMAS-XMLSOAP-ORG:SOAP.V1; Ns=42 "
42-soapmethodname:urn:bobnsid:ifoo#doit
The man header maps the soap URI to the prefix 42 header and indicates that the server that does not recognize soap must return an HTTP error, the status code is 501 (not implemented), or 510 (not expanded). The HTTP method must be M-post, indicating that it is currently a required header extension.
Conclusion
Soap is a typed serialization format that happens to use HTTP as a request/Response message Transfer Protocol. SOAP is designed to work in close collaboration with the XML Schema specification that is emerging and to support interoperability between COM, CORBA, Perl, TCL, and Java-language, C, Python, or PHP programs that run anywhere on the Internet.
I hope this article gives you a clearer understanding of the specifics of the agreement. I encourage you to experiment with soap, or try to use one of the SOAP-enabled systems (listed in http://www.develop.com/soap/) or do some work yourself. I personally found that using scripting language (JSCRIPT) enabled a basic SOAP client and server to be built and run for less than one hours. Depending on how familiar you are with HTTP and XML, and the maturity of your target platform, you will spend a different amount of time.