<soap>
SOAP (Simple Object Access Prototcol)

JavaScript: lz.soap
extends <rpc> » <node> » lz.Eventable »

SOAP (Simple Object Access Prototcol) is used to exchange information in a distributed environment. A typical scenarion involves a SOAP client invoking a client-side function stub to invoke a SOAP web service operation. The SOAP web service then returns data to the client, like stock information or the result to a math function. The SOAP protocol is a work in progress being drafted by the W3C. For the latest SOAP information.

The <soap> element creates a client-side representation of a SOAP service based on a WSDL. The name and wsdl attributes are required.

<canvas debug="true" height="530">
    
        <debug x="15" y="15" width="415" height="500"/>
        
        <soap name="amazon" wsdl="http://soap.amazon.com/schemas3/AmazonWebServices.wsdl">
        
            <handler name="onload">
                Debug.debug('Amazon soap service loaded');
                Debug.debug('Compare proxy stubs with WSDL SOAP operations.');
                Debug.debug('Amazon WSDL at %w', this.wsdl);            
                Debug.debug('proxy:');
                Debug.inspect(this.proxy);
            </handler>
            
            <handler name="onerror" args="error">
                Debug.debug('error: %w', error);
            </handler>
        
        </soap>
        
    </canvas>

Document style operations use XML (i.e. documents) as paramaters. Document style operations return an array of LzDataElements, though often only a single LzDataElement will exist in the array. The XML string (document) parameter passed into the operation must match the XML schema as defined in the WSDL.

<canvas debug="true">
    
        <debug y="30" x="145" width="350" height="300"/>
        
        <!-- This SOAP service uses document/literal messages for its
        operations. Each operation is passed a document as a parameter. -->
        <soap name="maths" wsdl="http://www.dotnetjunkies.com/quickstart/aspplus/samples/services/MathService/VB/MathService.asmx?WSDL">
        
            <!-- Method to make a document for SOAP message requests -->
            <method name="makedoc" args="func, av, bv"><![CDATA[
                
                if (func == null) return;
                var s =  '<' + func + ' xmlns="' + 'http://tempuri.org/' + '" >' + 
                    '<A>' + av + '</A>' + 
                    '<B>' + bv + '</B>' + 
                '</' + func + '>';
                Debug.debug("%w", s);
                return s;
                
            ]]></method>
            
            <handler name="onload">
            // make buttons visible once SOAP object is loaded
                canvas.buttons.setAttribute('visible', true);            
            </handler>
            
            <handler name="onerror" args="error">
                Debug.debug('error: %w', error);
            </handler>
            
            <handler name="ontimeout" args="error">
                Debug.debug('timeout: %w', error);
            </handler>
            
            <handler name="ondata" args="value">
            Debug.debug("%w", value);
                result.setAttribute('text', value);
            </handler>
            
            <remotecall funcname="Add">
                <param value="${ canvas.maths.makedoc(parent.name, a.text, b.text) }"/>
            </remotecall>
            <remotecall funcname="Subtract">
                <param value="${ canvas.maths.makedoc(parent.name, a.text, b.text) }"/>
            </remotecall>
            <remotecall funcname="Multiply">
                <param value="${ canvas.maths.makedoc(parent.name, a.text, b.text) }"/>
            </remotecall>
            <remotecall funcname="Divide">
                <param value="${ canvas.maths.makedoc(parent.name, a.text, b.text) }"/>
            </remotecall>
        </soap>
        
        <view name="buttons" x="10" y="10" visible="false" layout="spacing: 10">
            <text><b>.NET MathService</b></text>
            
            <view layout="axis: x"><text y="3">a:</text><edittext id="a" text="10"/></view>
            <view layout="axis: x"><text y="3">b:</text><edittext id="b" text="2"/></view>
            <view layout="axis: x"><text>result:</text><text id="result"/></view>
            
            <button text="add" onclick="canvas.maths.Add.invoke()"/>
            <button text="subtract" onclick="canvas.maths.Subtract.invoke()"/>
            <button text="multiply" onclick="canvas.maths.Multiply.invoke()"/>
            <button text="divide" onclick="canvas.maths.Divide.invoke()"/>
        
        </view>
        
    </canvas>

The XML Schema in the WSDL describes how the XML should be structured for each of the operations. The WSDL below describes how what the schema should look like for the Add operation.

    <definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
            xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
            xmlns:s="http://www.w3.org/2001/XMLSchema"
            xmlns:s0="http://tempuri.org/"
            xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
            xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
            xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
            targetNamespace="http://tempuri.org/"
            xmlns="http://schemas.xmlsoap.org/wsdl/">
    
    <types>
        <s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
            <s:element name="Add">
                <s:complexType>
                    <s:sequence>
                        <s:element minOccurs="1" maxOccurs="1" name="A" type="s:float" />
                        <s:element minOccurs="1" maxOccurs="1" name="B" type="s:float" />
                    </s:sequence>
                </s:complexType>
            </s:element>
            
            <s:element name="AddResponse">
                <s:complexType>
                    <s:sequence>
                        <s:element minOccurs="1" maxOccurs="1" name="AddResult" type="s:float" />
                    </s:sequence>
                </s:complexType>
            </s:element>
            
            <!-- MORE SCHEMA DECLARATION (for Subtract, Multiply, Divide) HERE -->
        
        </s:schema>
    </types>
    
    <message name="AddSoapIn">
        <part name="parameters" element="s0:Add" />
    </message>
    <message name="AddSoapOut">
        <part name="parameters" element="s0:AddResponse" />
    </message>
    
    <!-- OTHER MESSAGES (for Subtract, Multiply, Divide) HERE -->
    
    <portType name="MathServiceSoap">
        <operation name="Add">
            <input message="s0:AddSoapIn" />
            <output message="s0:AddSoapOut" />
        </operation>
        <!-- OTHER PORT TYPE OPERATIONS (for Subtract, Multiply, Divide) HERE -->
    </portType>
    
    <binding name="MathServiceSoap" type="s0:MathServiceSoap">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
        <operation name="Add">
            <soap:operation soapAction="http://tempuri.org/Add" style="document" />
            <input>
                <soap:body use="literal" />
            </input>
            <output>
                <soap:body use="literal" />
            </output>
        </operation>
        <!-- OTHER SOAP BINDING OPERATIONS (for Subtract, Multiply, Divide) HERE -->
    </binding>
    
    <service name="MathService">
        <port name="MathServiceSoap" binding="s0:MathServiceSoap">
            <soap:address location="http://www.dotnetjunkies.com/quickstart/aspplus/samples/services/MathService/VB/MathService.asmx" />
        </port>
    </service>
    
    </definitions>
                

RPC style operations behave just like functions in that, instead of documents, values are passed in as parameters. Parameters can be of simple data type (number, boolean), array, or object. The parameter type for the operation is described in the WSDL's XML schema.

<canvas debug="true" height="400" width="530">
      
          <debug x="10" y="190" width="510" height="200"/>
          
          <dataset name="googleDset"/>
          
          <soap name="google" wsdl="http://api.google.com/GoogleSearch.wsdl">
              <handler name="onload">
                  Debug.debug('google soap service loaded');
              </handler>
              
              <handler name="onerror" args="error">
                  Debug.debug('error: %w', error);
              </handler>
              
              <!-- See RPC chapter for details on remotecall and how dataobject is
              used to data bind to RPC operation results. --> 
              <remotecall name="search" funcname="doGoogleSearch" dataobject="googleDset">
              
                  <param value="'2TKUw4ZQFHJ84ByemZK0EXV0Lj+7xGOx'"/>
                  <param value="${ s.text }"/>
                  <param value="1"/>
                  <param value="10"/>
                  <param value="true"/>
                  <param value="''"/>
                  <param value="true"/>
                  <param value="''"/>
                  <param value="''"/>
                  <param value="''"/>
                  
                  <handler name="ondata" args="value">
                      Debug.debug('search result: %w\n', value);
                  </handler>
              
              </remotecall>
          </soap>
          
          <view x="10" y="10" layout="spacing: 5">
              <view layout="axis: x; spacing: 5">
                  <edittext id="s" text="SOAP"/>
                  <button text="search" onclick="Debug.debug('Invoking search...'); google.search.invoke()"/>
              </view>
                  
              <view width="505" height="140" bgcolor="silver" layout="axis: y">
                  <view>
                      <datapath xpath="googleDset:/resultElements/item" pooling="true"/>
                      <text width="200" datapath="title/text()" clip="true"/>
                      <text x="205" width="300" datapath="URL/text()" clip="true"/>
                  </view>
              </view>
          
          </view>
      
      </canvas>

The example demonstrates how a result value, which is actually a JavaScript object, can be data bound through the dataobject attribute in remotecall. For more details, see the remotecall section in the RPC chapter of the Developer's Guide. To read about passing complex type parameters, read the SOAP chapter.

See Also:

Attributes

Name (CSS property) Type (tag) Type (js) Default Category
port string String   read/write
  The SOAP port to use. If not specified, the first SOAP port encountered in the WSDL is used.
proto expression any null readonly
  The prototypes that can be used to create objects.
requestheaders expression any null read/write
  The SOAP header to pass with each request. This can be either a string or a dataset. Default is null.
responseheaders expression any null read/write
  If set, the SOAP response header returned by the last call. The value for this must be a dataset. Default is null.
service string String   read/write
  The SOAP service to fetch. If not specified, the first service encountered in the WSDL is used.
wsdl string String   read/write
  Required attribute that specifies WSDL to read for the SOAP object. The value for wsdl should be an href.

Attributes inherited from <rpc>

autoload, proxy, proxyinfo, secure, secureport

Methods

load()
soap.load();
Load the object. If successful, this.proxy is set to an object with remote APIs.

makeProxyStubFunction()
soap.makeProxyStubFunction(fn);
Parameter Name Type Description
fn    

Methods inherited from <rpc>

load, makeProxyStubFunction, unload

Methods inherited from lz.Eventable

destroy, setAttribute

Events

Events inherited from <rpc>

ondata, onerror, onload, onunload

Events inherited from <node>

onconstruct, ondata, oninit

Events inherited from lz.Eventable

ondestroy