Complex Nested Parameters

During WSDL Import with the U2.0 Soap connector, Uniface examines the parameters of web service operations for their complexity. If Uniface cannot handle a parameter because of its complexity, it defines that parameter as a string.

In such cases, special handling is required when activating the operation, and as the developer, you need to provide the complex data as a well-formed XML string. To do so, you need to examine the element definitions.

Note:  The following information is not applicable when the binding style of the service is Document/Literal Bare. In this case, parameters are treated as XML documents, with one XML document for IN parameters and another for OUT parameters. As the developer, you need to provide the XML document, element, and contents for the parameters.

IN Parameters

For IN parameters, you must create the string with the correct XML content as defined for that parameter in the WSDL file. The string should be a self-contained, well-formed snippet of XML, meaning that:

  • It should not start with an xml declaration such as <?xml version="1.0" encoding="utf-8"?>
  • It should define and use its own namespaces locally (this is what is meant by self-contained). The actual namespace can be obtained from the Uniface signature or from the WSDL file.

Element definitions in the WSDL file specify whether or not each element may appear more than once, based on the maxoccurs attribute.

  • If the element definition can appear zero or one time, Uniface provides the element.
  • If the element may appear more than once, you must provide the element and its contents.

    If the parameter is empty/null, you must still provide the element, if applicable:

    • If the element is defined with the attribute minoccurs="0", it is optional and you do not need to provide it.
    • If the element is defined with the attribute nillable="true"', the element must be provided with the nil="true".

The Uniface SOAP connector will generate the SOAP envelope and insert the parameter element as if it were a simple string. To provide the complex content for the parameter, you must either provide it as the parameter value in the activate call of the SOAP operation, or manipulate the value in the SOAP_CALLOUT_PRE callback operation.

When providing the complex content as a parameter in the activate call, you need to provide the element content without the enclosing parameter element. This XML snippet may consist of several sibling elements once the root parameter element is removed. You need to ensure that each sibling element has its own namespace defined locally.

For example, a complex parameter may be generated in the XML template as:

<uwi0:parameter1 xmlns:uwi0="urn:uniface:applic:wrapped:services:NS_1">
  <uwi0:nested_type_1>
    <uwi0:element1>string</uwi0:element1>
  </uwi0:nested_type_1>
  <uwi0:nested_type_2>
    <uwi0:element1>string</uwi0:element1>
  </uwi0:nested_type_2>
  <uwi0:nested_type_3>
    <uwi0:element1>string</uwi0:element1>
  </uwi0:nested_type_3>
</uwi0:parameter1>

Because the SOAP connector will generate the parameter1 element itself, you need only provide the content as the parameter value in the activate statement. Each sibling element defines its own namespace.

<uwi0:nested_type_1 xmlns:uwi0="urn:uniface:applic:wrapped:services:NS_1">
    <uwi0:element1>string</uwi0:element1>
  </uwi0:nested_type_1>
  <uwi0:nested_type_2 xmlns:uwi0="urn:uniface:applic:wrapped:services:NS_1">
    <uwi0:element1>string</uwi0:element1>
  </uwi0:nested_type_2>
  <uwi0:nested_type_3 xmlns:uwi0="urn:uniface:applic:wrapped:services:NS_1">
    <uwi0:element1>string</uwi0:element1>
  </uwi0:nested_type_3>

Note:  This technique cannot be used when the parameter element is defined with attributes. The SOAP connector will not generate them so you need to use the SOAP_CALLOUT_PRE callback technique.

When using the SOAP_CALLOUT_PRE callback operation, you still need to provide a value for the activate parameter. This can be a simple string, possibly an easily recognizable string that acts as a placeholder.

The callback function receives the generated envelope. You now have full control of how to handle the parameter. For example, you can scan the envelope for the parameter start and end elements and replace the whole parameter. This would certainly be required if the parameter element requires attributes. Alternatively you could simply replace the string that was provided as the parameter value in the activate call, with the XML content of the parameter, (removing the parameter root element), as described above. Either way, namespaces must be locally defined.

OUT Parameters

For OUT parameters, Uniface provides the parameter as a complete XML document so that it can be easily parsed by an XML parser. To do this, Uniface adds an XML declaration and provides a document root element to encompass the XML that was returned in the SOAP envelope for that parameter. The document root element name is named parameter and has a namespace URN of urn:uniface:applic:complexparameter. Uniface generates local namespace prefixes and definitions to make the returned XML self-contained. No assumptions should be made about the style, form, or literal value of the prefixes. These are implementation details and may change in future.

RPC Style Web Service

For RPC style web services, parameters are considered to be the parts of the WSDL message defined for the operation. For example, an RPC operation called RPCOperation may be defined as sending a message called RPCOperationRequest:

<wsdl:message name="RPCOperationRequest">
  <wsdl:part name="b" type="s:byte" />
  <wsdl:part name="s" type="s:short" />
  <wsdl:part name="c" type="tns:ComplexStructureOfInts" />
</wsdl:message>

In this case, the Uniface import defines three IN parameters for the operation. The third parameter is of type String and you need to provide it according to the type definition of ComplexStructureOfInts.

Document Literal Wrapped Web Service

For Document Literal Wrapped web services, the WSDL message defines the operation wrapper and the parameters are the elements within that wrapper element. For example, for a wrapped operation DLWOperation, the message sent to the web service is called DLWOperationRequest:

<s:element name="DLWOperation" type="tns:complex" />
<s:complexType name="complex">
  <s:sequence>
    <s:element name="param1" type="s:int" />
    <s:element name="param2" type="s:int" />
    <s:element name="param3" type="tns:ComplexNested" />    
  </s:sequence>
</s:complexType>

<wsdl:message name="DLWOperationRequest">
  <wsdl:part name="parameters" element="tns:DLWOperation" />
</wsdl:message>

In this case, three IN parameters are defined. You need to provide an XML snippet string for param3 that conforms to the definition of the type ComplexNested.

Document Literal Bare Web Service

For Document Literal Bare web services, Uniface generalizes the operations into sending one XML document to the web service and, if any output is defined in the WSDL, receiving one XML document from the web service. Uniface defines one string IN parameter and one string OUT parameter which encapsulates the complete XML content sent to and received from the web service operation. This is in contrast to other styles of web service, where actual parameters are recognized and handled individually. These bare parameters must be provided according to the rules for complex nested parameters.

For example, a Document Literal Bare web service has an operation called DLBOperation with a namespace of http://tempuri.org/bareService. In the WSDL, a portType defines the XML content that will be sent to and received from the web service for this operation:

<wsdl:operation name="DLBOperation">
  <wsdl:input message="tns:DLBOperationSoapIn" />
  <wsdl:output message="tns:DLBOperationSoapOut" />
</wsdl:operation>

The messages are defined as elements belonging to a particular namespace:

<wsdl:message name="DLBOperationSoapIn">
  <wsdl:part name="cwa1" element="tns:cwa1" />
</wsdl:message>
<wsdl:message name="DLBOperationSoapOut">
  <wsdl:part name="cwa2" element="tns:cwa2" />
</wsdl:message>

The elements are defined by their types:

<s:element name="cwa1" type="tns:ComplexWithAttributes" />
<s:element name="cwa2" type="tns:ComplexWithAttributes" />

<s:complexType name="ComplexWithAttributes">
  <s:sequence>
    <s:element minOccurs="0" maxOccurs="1" name="elem" type="s:string" />
  </s:sequence>
  <s:attribute name="attr" type="s:string" />
</s:complexType>

The Uniface signature for this operation is defined with one IN string parameter and one OUT string parameter.

You must provide the IN parameter as a well formed, self contained XML snippet that conforms exactly to the WSDL definition of the input message. Notice the local namespace definition:

<local0:cwa1 xmlns:local0:="http://tempuri.org/bareService" xmlns:local1="" local1:attr="string attr">
    <local0:elem>string elem</local0:elem>
</local0:cwa1>

The OUT parameter is returned as a complete XML document, again with local namespace definitions. Prefixes should be identified through normal XML parsing, do not rely on them being called local0:

<?xml version="1.0" encoding="UTF-8"?>
<ufnc:parameter xmlns:ufnc="urn:uniface:applic:complexparameter">
 <local0:cwa2 xmlns:local0="http://tempuri.org/bareService" xmlns:local1="" local1:attr="string attr">
  <local0:elem>attr</local0:elem>
 </local0:cwa2>
</ufnc:parameter>

Related Topics