Los nodos SOAP se configuran utilizando un enlace WSDL específico que tiene un estilo de document (valor predeterminado) o rpc. Todas las operaciones definidas en un enlace WSDL determinado suelen definirse con el mismo uso, que puede ser literal (valor predeterminado) o encoded.
Los mensajes SOAP que son rpc-encoded pueden realizar anotaciones de codificación SOAP diseñadas para dar al receptor información adicional sobre el mensaje que se envía. Los siguientes cuatro tipos de anotaciones son comunes:
Un atributo xsi:type puede añadirse a un elemento para especificar su tipo. Por ejemplo:
<data xsi:type="xsd:string">text</data>
donde el prefijo xsi espacio de nombres definidos de la siguiente manera:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
Para un servicio web creado a partir de esquema WSDL y XML, la información de tipo ya está disponible y xsi:type es redundante.
Generalmente, cuando se crea un mensaje de salida, no añade información xsi:type. El siguiente ejemplo de ESQL muestra cómo agregar información xsi:type si es necesario:
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';
Cuando se analiza un mensaje de entrada, cualquier información de xsi:type se añade en el árbol lógico de la misma manera que otros atributos, tal como se muestra a continuación:
(0x03000000:PCDataField):data = 'text' (CHARACTER)
(
(0x03000100:Attribute)http://www.w3.org/2001/XMLSchema-instance:type = 'xsd:string' (CHARACTER)
)
Se puede añadir un atributo encodingStyle a un elemento para especificar el estilo de codificación SOAP utilizado. Por ejemplo:
<tns:op1 soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
donde el prefijo soapenv se define como el espacio de nombres de su sobre SOAP, del modo siguiente:
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" (SOAP 1.1)
xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" (SOAP 1.2)
El valor en sí es una lista de URIs, pero los valores de uso común son los siguientes:
"http://schemas.xmlsoap.org/soap/encoding/" (SOAP 1.1)
"http://www.w3.org/2003/05/soap-encoding" (SOAP 1.2)
En SOAP 1.1, el atributo encodingStyle se puede añadir a cualquier elemento. En SOAP 1.2, el atributo encodingStyle sólo se puede añadir a los hijos de Body, Header y Detail.
En general, creará un mensaje de salida, pero no añadirá el atributo encodingStyle. El siguiente ejemplo de ESQL muestra cómo agregar información encodingStyle, si es necesario:
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;
Cuando se analiza un mensaje de entrada, los atributos encodingStyle se añaden en el árbol lógico de la misma manera que otros atributos, tal como se muestra a continuación:
(0x03000100:Attribute)http://schemas.xmlsoap.org/soap/envelope/:encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/' (CHARACTER)
Una matriz SOAP es un elemento que contiene una secuencia de los elementos hijo del mismo tipo. En el siguiente ejemplo de esquema XML, existe un tipo denominado data con dos elementos: una cadena simple y una matriz. En el esquema, el campo denominado array tiene un número indeterminado de hijos de tipo serie. El nombre de los elementos hijo no se ha especificado.
<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>
Los espacios de nombres utilizados en el ejemplo son de WSDL 1.1 y SOAP 1.1, del modo siguiente:
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
El ejemplo siguiente es parte de un documento de instancia válido que coincide con el esquema:
<array soapenc:arrayType="xsd:string[]">
<item>item1</item>
<item>item2</item>
</array>
Cuando se crea un mensaje de salida, debe añadir los atributos apropiados. Por ejemplo, el ESQL siguiente muestra cómo añadir el atributo arrayType:
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[]';
Los atributos utilizados por SOAP 1.1 y SOAP 1.2 son distintos. SOAP 1.1 utiliza el atributo arrayType. Puede especificarse el tamaño de la matriz, aunque no es necesario. SOAP 1.2 utiliza dos atributos independientes. Los atributos SOAP 1.2 equivalentes del ejemplo anterior son soapenc:itemType="xsd:string" y soapenc:arraySize="2", donde los prefijos de espacio de nombres se definen como se muestra a continuación:
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc=" http://www.w3.org/2003/05/soap-encoding"
Debe inhabilitar la validación si el flujo de mensajes recibe mensajes con matrices SOAP codificadas con SOAP. El documento de instancia no puede validarse con el esquema al analizar un mensaje entrante porque el nombre de los elementos de matriz no ha sido definido por el esquema.
En el ejemplo siguiente se muestra un mensaje de solicitud SOAP 1.1 para una operación WSDL rpc-encoded denominado 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>
Una implementación SOAP puede reorganizar este mensaje lógico para utilizar elementos de referencia, del modo siguiente:
<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>
El mensaje es lógicamente equivalente al del primer ejemplo, pero los hijos de los elementos p1 y array han sido divididos en elementos hermanos diferentes a los que, posteriormente, se hace referencia utilizando el atributo href.
Los elementos introducidos como, por ejemplo, <data>:
Ninguna de estas consideraciones se aplica en el ejemplo anterior.
Generalmente, cuando cree un mensaje de salida, no deber codificar varios elementos de referencia a menos que el mensaje represente un gráfico. De lo contrario, la codificación de varios elementos de referencia es opcional. El siguiente ejemplo de ESQL muestra cómo codificar varios elementos de referencia:
-- 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';
Cuando se analiza un mensaje de entrada, los elementos multireferencia no coinciden con el esquema XML del servicio web WSDL. Si la validación está habilitada en un nodo SOAP se genera una excepción. Si utiliza la codificación de varias referencias, debe inhabilitar la validación.
Cuando cree un árbol lógico a partir del mensaje, puede propagar este árbol a otro nodo SOAP para la salida. Por ejemplo, con un flujo de fachada como se muestra en el siguiente diagrama, si el nodo SOAPRequest recibe una respuesta utilizando codificación de multireferencia, puede propagar el árbol lógico de la respuesta al nodo SOAPReply, y se devuelve un mensaje SOAP con la codificación multireferencia al cliente original.
El cliente original también debe comprender la codificación multireferencia.
Para manipular el árbol lógico para un mensaje con codificación multireferencia, navegue hasta los atributos href e id en ESQL. Estos atributos son ligeramente distintos en SOAP 1.1 y SOAP 1.2, del modo siguiente: