WSDL: Difference between revisions

From DataFlex Wiki
Jump to navigationJump to search
Adding...
m minor tweak
 
(9 intermediate revisions by the same user not shown)
Line 3: Line 3:
WSDL is most commonly automatically generated by the service software - this is the case with [[Visual DataFlex]] - but in some cases, where the software used does not provide this capability, it may be hand-written. This latter case can produce some very idiosyncratic and non-standard WSDL that causes problems for service consumers.
WSDL is most commonly automatically generated by the service software - this is the case with [[Visual DataFlex]] - but in some cases, where the software used does not provide this capability, it may be hand-written. This latter case can produce some very idiosyncratic and non-standard WSDL that causes problems for service consumers.


If your software platform or toolkit provides for automatic generation of WSDL from your own services, and for automatic creation of ''proxy'' or ''stub'' client code from other people's services, then it should never be necessary to understand the complexities of WSDL... ''until somethings goes wrong!'' Then you may have to ''"look under the hood"''.
If your software platform or toolkit provides for automatic generation of WSDL from your own services, and for automatic creation of ''proxy'' or ''stub'' client code from other people's services, then it should never be necessary to understand the complexities of WSDL... ''until something goes wrong!'' Then you may have to ''"look under the hood"''.


(''Note: I will be describing WSDL 1.x here - 2.0 is different in a number of regards. [[User:Mikepeat|Mike]]'')
(''Note: I will be describing WSDL 1.x here - 2.0 is different in a number of regards. [[User:Mikepeat|Mike]]'')


==Structure==
==Structure==
WSDL can be quite formidable to understand for those not used to looking at such things. Probably the easiest way to get to grips with is is to break it down into its various components.
WSDL can be quite formidable to understand for those not used to looking at such things. Probably the easiest way to get to grips with it is to break it down into its various components.


After any initial processing instruction (<?xml version="1.0" encoding="UTF-8"?> or similar) there will be the outer '''<description>''' element, which will typically also define a number of '''''[[namespace]]s''''' that will be used in the document.
After any initial processing instruction (<?xml version="1.0" encoding="UTF-8"?> or similar) there will be the outer '''<definitions>''' element, which will typically also define a number of '''''[[XML namespaces]]''''' that will be used in the document.


Within that there will (usually, and in WSDL 1.1) be four or five main types of element, grouped together, in the following order:
Within that there will (usually, and in WSDL 1.1) be four or five main kinds of element, grouped together, in the following order:


*'''types''' - only one element (optional) describing the extended data types used by the service
*'''types''' - only one element (optional) describing the extended data types used by the service
*'''message''' - defining the in and out messages used by the service's operations
*'''message''' - defining the in and out messages used by the service's operations
*'''portType''' - defining the abstract definition of the service
*'''portType''' - the abstract definition of the service
*'''binding''' - providing a link between the abstract definition and the concrete implementation
*'''binding''' - providing a link between the abstract definition and the concrete implementation
*'''service''' - the concrete specification of a service
*'''service''' - the concrete specification of a service
Line 22: Line 22:
This arrangement is convenient for machines to read, as each part is defined prior to encountering the parts that use it, but it is confusing for humans, so for that reason we will deal with those sections in reverse order.
This arrangement is convenient for machines to read, as each part is defined prior to encountering the parts that use it, but it is confusing for humans, so for that reason we will deal with those sections in reverse order.


===The "''description''" element===
===The "''definitions''" element===
The description element, as well as serving as the XML document root, also defines (some of) the namespaces used in the document.  Typically these will include:
The definitions element, as well as serving as the XML document root, also defines (some of) the namespaces used in the document.  Typically these will include:


* The base WSDL namespace: ="<span style="color:midnightblue;">xmlns="<nowiki>http://schemas.xmlsoap.org/wsdl/</nowiki>"</span>
* The base WSDL namespace: <span style="color:midnightblue;">xmlns="<nowiki>http://schemas.xmlsoap.org/wsdl/</nowiki>"</span>
* The XML Schema namespace, where the base XML types are defined: ="<span style="color:midnightblue;">xmlns:xs="<nowiki>http://www.w3.org/2001/XMLSchema</nowiki>"</span>
* The XML Schema namespace, where the base XML types are defined: <span style="color:midnightblue;">xmlns:xs="<nowiki>http://www.w3.org/2001/XMLSchema</nowiki>"</span>
* The [[SOAP]] namespace: ="<span style="color:midnightblue;">xmlns:soap<nowiki>"http://schemas.xmlsoap.org/wsdl/soap/</nowiki>"</span>
* The [[SOAP]] namespace: <span style="color:midnightblue;">xmlns:soap="<nowiki>http://schemas.xmlsoap.org/wsdl/soap/</nowiki>"</span>
* The service's own namespace, which is usually associated with the namespace prefix "tns" - ('''t'''his '''n'''ame'''s'''pace): ="<span style="color:midnightblue;">xmlns:tns="http://''yourDomain/yourService/serviceName''"</span>
* The service's own namespace, which is usually associated with the namespace prefix "tns" - ('''t'''his '''n'''ame'''s'''pace): <span style="color:midnightblue;">xmlns:tns="http://''yourDomain/yourService/serviceName''"</span>
* The "target" namespace, which is often identical to the "tns" one: ="<span style="color:midnightblue;">targetNamespace="http://''yourDomain/yourService/serviceName''"</span>
* The "target" namespace, which is generally identical to the "tns" one: <span style="color:midnightblue;">targetNamespace="http://''yourDomain/yourService/serviceName''"</span>


There may be ''many'' more than these (look at any Microsoft .Net service WSDL), but most services will define at least these ones as a minimum, although not always in exactly that form. In particular, the choice of namespace prefixes is arbitrary, so the base namespace might be specified as "xmlns:wsdl", rather than just "xmlns"; "xmlns:xs" is often seen as "xmlns:xsd"; "xmlns:soap" might be "xmlns:soap12" (in reference to SOAP 1.2) or many other variations - remember that it is the actual namespace URI that is being referenced that is important, not the prefix used to represent it ikn the document, which can be anything.
There may be ''many'' more than these (look at any Microsoft .Net service WSDL), but most services will define at least these ones as a minimum, although not always in exactly this form. In particular, the choice of namespace prefixes is arbitrary, so the base namespace might be specified as "xmlns:wsdl", rather than just "xmlns"; "xmlns:xs" is often seen as "xmlns:xsd"; "xmlns:soap" might be "xmlns:soap11" (in reference to SOAP 1.1) or many other variations - remember that it is the actual namespace URI which is being referenced that is important, not the prefix used to represent it in the document, which can be anything.


===The "''service''" element===
===The "''service''" element===
Although the last of the children of the <description> element, the '''service''' element is the natural starting point for human WSDL readers.  There ''can'' be more than one service defined in a single WSDL document, which is sometimes sensible for describing different physical services which share the same logical definition (a service provider might provide the same service from a number of different network locations - i.e. servers - to provide redundancy, or multiple services might share some aspects, in particular data types, in common), however most commonly only a single service will be described.
Although the last of the children of the <description> element, the '''service''' element is the natural starting point for human WSDL readers.  There ''can'' be more than one service defined in a single WSDL document, which is sometimes sensible for describing different physical services which share the same logical definition (a service provider might provide the same service from a number of different network locations - i.e. servers - to provide redundancy, or multiple services might share some aspects, in particular data types, in common), however most commonly only a single service will be described.


Like most of the WSDL main elements, the service element can have a <documentation> element within it.  In [[Visual DataFlex]] you can set this via the "psDocumentation" property of the Web Service object.  It will also have a '''name''' attribute, which will be whatever you set the psServiceName property of your Web Service object to.
As with serveral of the WSDL main elements, the service element can have a <documentation> element within it.  In [[Visual DataFlex]] you can set this via the "psDocumentation" property of the Web Service object.  It will also have a '''name''' attribute, which will be whatever you set the psServiceName property of your Web Service object to.


The crucial element within the service is the '''<port>'''. This defines an implementation of the service as a network resource and has a "binding" attribute which will usually point to a <binding> element (see below) in the same WSDL document (and hence will tend to have the namespace prefix "tns": this nampespace).  This will attribute will lead us on our trail, ''up'' the WSDL, to our next stop, the binding element.
The crucial element within the service is the '''<port>'''. This defines an implementation of the service as a network resource and has a "binding" attribute which will point to a '''<binding>''' element (see below) in the same WSDL document (and hence will tend to have the namespace prefix "tns": this namespace).  This will attribute will lead us on our trail, ''up'' the WSDL, to our next stop, the binding element.


While there are sometimes other protocols defined (HTTP, SMTP, FTP, etc.), the commonest by far is for SOAP, so within the <port> element it is common to find a '''<soap:address>''' element, specifying, via its "location" attribute, the actual [[URI]] through which the service can be invoked.
While there are sometimes other protocols defined (HTTP, SMTP, FTP, etc.), the commonest by far is for SOAP, so within the <port> element it is common to find a '''<soap:address>''' element, specifying, via its "location" attribute, the actual [[URI]] through which the service can be invoked.


===The "''binding''" element===
===The "''binding''" element===
The '''binding''' element is what joins the physical implementation of the secvice - a <port> element within the <service> element - to its logical (or abstarct) definition, which is represented by the <portType> element (see below).
The '''binding''' element is what joins the physical implementation of the service - a <port> element within the <service> element - to its logical (or abstract) definition, which is represented by the <portType> element (see below).


The binding element will have two attributes which effect this joining: its '''name''' attribute, which is what is pointed to by the ''binding'' attribute of the service "port" element above, and its '''type''' attribute which in turn points to a "portType" (again, usually defined within the same WSDL document and hence having a "tns" prefix.
The binding element will have two attributes which effect this joining: its '''name''' attribute, which is what is pointed to by the ''binding'' attribute of the service "port" element above, and its '''type''' attribute which in turn points to a "portType" (again, usually defined within the same WSDL document and hence having a "tns" prefix).


Within the binding element there will be one or more protocol binding elements, the most common of which is the '''<soap:binding>'''. This will define the SOAP ''style'' attribute, either "[[RPC Style SOAP|rpc]]" or "[[Document Style SOAP|document]]", and a ''transport'' element, set to a URI defining that, such as "<nowiki>http://schemas.xmlsoap.org/soap/http</nowiki>".
Within the binding element there will be one or more protocol binding elements, the most common of which is the '''<soap:binding>'''. This will define the SOAP ''style'' attribute, either "[[RPC Style SOAP|rpc]]" or "[[Document Style SOAP|document]]", and a ''transport'' element, set to a URI defining that, such as "<nowiki>http://schemas.xmlsoap.org/soap/http</nowiki>".
Line 53: Line 53:
Each of these will contain first a operation protocol binding, such as '''<soap:binding>''' which will again define a ''style'' attribute and also a ''soapAction'' attribute; this latter will appear as the HTTP Header field "''SOAPAction''" in the messages sent to and from the operation (in Visual DataFlex services this is set to an empty string).
Each of these will contain first a operation protocol binding, such as '''<soap:binding>''' which will again define a ''style'' attribute and also a ''soapAction'' attribute; this latter will appear as the HTTP Header field "''SOAPAction''" in the messages sent to and from the operation (in Visual DataFlex services this is set to an empty string).


Following this there will be '''<input>''' and '''<output>''' elements for the operation, containing a definition of the way data is to be passed in the messages. Typically this will take the form of a '''<soap:body>''' element with a ''use'' attribute specifying either "literal" or "encoded.  If an "encoded" usage is specified then an ''encodingStyle'' attribute may be present, pointing to a URI defining the style, such as "<nowiki>http://schemas.xmlsoap.org/soap/encoding/</nowiki>". There may also be a ''namespace'' attribute, for specifying a specific namespace for the operation.  Additionally may be a '''<soap:header>''' element, but discussion of this falls outside the scope of this article.
Following this there will be '''<input>''' and '''<output>''' elements for the operation, containing a definition of the way data is to be passed in the messages. Typically this will take the form of a '''<soap:body>''' element with a ''use'' attribute specifying either "literal" or "encoded.  If an "encoded" usage is specified then an ''encodingStyle'' attribute may be present, pointing to a URI defining the style, such as "<nowiki>http://schemas.xmlsoap.org/soap/encoding/</nowiki>". There may also be a ''namespace'' attribute, for specifying a specific namespace for the operation.  Additionally there may be a '''<soap:header>''' element, but discussion of this falls outside the scope of this article.


===The "''portType''" element===
===The "''portType''" element===
The '''portType''' element is the abstract representation of the service and is identified by its ''name'' attribute (what the ''type'' attribute of a ''binding'' elememt points to).
The '''portType''' element is the abstract representation of the service and is identified by its ''name'' attribute (what the ''type'' attribute of a ''binding'' element points to).


It will contain a number of '''operation''' elements, one for each operation of the service.
It will contain a number of '''operation''' elements, one for each operation of the service.


Each operation ''may'' contain a '''documentation''' element, describing the operation (in Visual DataFlex you can set this through the "{ Description = }" meta-data tag that preceeds your published Function or Procedure).
Each operation ''may'' contain a '''documentation''' element, describing the operation (in Visual DataFlex you can set this through the "{ Description = }" meta-data tag that precedes your published Function or Procedure).


There will then be '''<input>''' and '''<output>''' elements, each of which will contain a ''message'' attribute, pointing to (the ''name'' attribute of) a '''message''' element (see below) which will hold the definition of that input or output message. Such message elements will usually appear within the same WSDL document and thus will commonly have the "tns" prefix.
There will then be '''<input>''' and '''<output>''' elements, each of which will contain a ''message'' attribute, pointing to (the ''name'' attribute of) a '''message''' element (see below) which will hold the definition of that input or output message. Such message elements will usually appear within the same WSDL document and thus will commonly have the "tns" prefix.
Line 72: Line 72:


===The "''types''" element===
===The "''types''" element===
The '''types''' element is optional, but is generally required for any non-trivial services, especially those of Document-style. There is only ever one types element in a WSDL document.


Within the types element there will be one or more '''<schema>''' elements within the "<nowiki>http://www.w3.org/2001/XMLSchema</nowiki>" namespace. Within ''these'' will be the definitions of all the data types used by the service, beyond the XML primitive types, and in fact in Document-style services even the most primitive data type (including none at all!) is generally referenced to a specific definition in a schema.


[[Category: Web Services]] [[Category:WIP]]
The topic of XML schema definitions is beyond the scope of this article however, so our investigation of the elements of WSDL, and their decomposition, must end there.
 
==Example==
To illustrate the above here is a sample of a very simple (it takes a single string as a parameter and returns another string) service WSDL: start from the '''''service''''' element at the bottom and work up through the various elements to the '''''types''''' definitions:
 
<?xml version="1.0" encoding="UTF-8" ?>
<'''definitions''' xmlns="<nowiki>http://schemas.xmlsoap.org/wsdl/</nowiki>"
              xmlns:xs="<nowiki>http://www.w3.org/2001/XMLSchema</nowiki>"
              xmlns:soap="<nowiki>http://schemas.xmlsoap.org/wsdl/soap/</nowiki>"
              xmlns:tns="<nowiki>http://unicorninterglobal.com/sample/</nowiki>"  <span style="color:red">--set from psServiceURI</span>
              name="Hello"
              targetNamespace="<nowiki>http://unicorninterglobal.com/sample/</nowiki>">  <span style="color:red">--set from psServiceURI</span>
 
  <'''types'''>
    <xs:schema elementFormDefault="qualified" targetNamespace="<nowiki>http://unicorninterglobal.com/sample/</nowiki>">
      <xs:element name="'''SayHello'''">          <span style="color:red">--link from input message</span>
        <xs:complexType>
          <xs:sequence>
            <xs:element name="sName" type="'''xs:string'''" />  <span style="color:red">--and in the end it is just a string!</span>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="'''SayHelloResponse'''">  <span style="color:red">--link from output message</span>
        <xs:complexType>
          <xs:sequence>
            <xs:element name="SayHelloResult" type="'''xs:string'''" />  <span style="color:red">--and so it this one!</span>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>
  </types>
  <'''message''' name="'''SayHelloSoapRequest'''">                        <span style="color:red">--link from portType</span>
    <part name="parameters" element="'''tns:SayHello'''" />        <span style="color:red">--link to type definition</span>
  </message>
  <'''message''' name="'''SayHelloSoapResponse'''">                      <span style="color:red">--link from portType</span>
    <part name="parameters" element="'''tns:SayHelloResponse'''" /> <span style="color:red">--link to type definition</span>
  </message>
  <'''portType''' name="'''HelloSoapType'''">                    <span style="color:red">--link from binding</span>
    <operation name="SayHello">
      <documentation>This operation says 'Hello!'</documentation> <span style="color:red">--set from <span style="color:gray">{ Description = "..."  }</span> meta-data on function</span>
      <input message="'''tns:SayHelloSoapRequest'''" />    <span style="color:red">--link to message</span>
      <output message="'''tns:SayHelloSoapResponse'''" />  <span style="color:red">--link to message</span>
    </operation>
  </portType>
  <'''binding''' name="'''HelloSoapBinding'''" type="'''tns:HelloSoapType'''">  <span style="color:red">--links ''from'' service and ''to'' portType</span>
    <soap:binding style="document" transport="<nowiki>http://schemas.xmlsoap.org/soap/http</nowiki>" />
    <operation name="SayHello">
      <soap:operation soapAction="" style="document" />
      <input>
        <soap:body use="literal" />
      </input>
      <output>
        <soap:body use="literal" />
      </output>
    </operation>
  </binding>
  <'''service''' name="Hello">
    <documentation>Sample documentation for the service</documentation>      <span style="color:red">--set from psDocumentation</span>
      <port name="HelloSoap" binding="'''tns:HelloSoapBinding'''">                  <span style="color:red">--connects to the "binding" element</span>
        <soap:address location="<nowiki>http://www.sample.com/services/Hello.wso</nowiki>" />  <span style="color:red">--service endpoint URI</span>
      </port>
  </service>
 
[[Category: Web Services]]

Latest revision as of 13:12, 3 April 2008

WSDL [1] - Web Service Description Language - is the mechanism for specifying the contract that a service offers to its clients. It is an XML dialect and either pronounced with the letters in full or as "wiz-dul".

WSDL is most commonly automatically generated by the service software - this is the case with Visual DataFlex - but in some cases, where the software used does not provide this capability, it may be hand-written. This latter case can produce some very idiosyncratic and non-standard WSDL that causes problems for service consumers.

If your software platform or toolkit provides for automatic generation of WSDL from your own services, and for automatic creation of proxy or stub client code from other people's services, then it should never be necessary to understand the complexities of WSDL... until something goes wrong! Then you may have to "look under the hood".

(Note: I will be describing WSDL 1.x here - 2.0 is different in a number of regards. Mike)

Structure

WSDL can be quite formidable to understand for those not used to looking at such things. Probably the easiest way to get to grips with it is to break it down into its various components.

After any initial processing instruction (<?xml version="1.0" encoding="UTF-8"?> or similar) there will be the outer <definitions> element, which will typically also define a number of XML namespaces that will be used in the document.

Within that there will (usually, and in WSDL 1.1) be four or five main kinds of element, grouped together, in the following order:

  • types - only one element (optional) describing the extended data types used by the service
  • message - defining the in and out messages used by the service's operations
  • portType - the abstract definition of the service
  • binding - providing a link between the abstract definition and the concrete implementation
  • service - the concrete specification of a service

This arrangement is convenient for machines to read, as each part is defined prior to encountering the parts that use it, but it is confusing for humans, so for that reason we will deal with those sections in reverse order.

The "definitions" element

The definitions element, as well as serving as the XML document root, also defines (some of) the namespaces used in the document. Typically these will include:

  • The base WSDL namespace: xmlns="http://schemas.xmlsoap.org/wsdl/"
  • The XML Schema namespace, where the base XML types are defined: xmlns:xs="http://www.w3.org/2001/XMLSchema"
  • The SOAP namespace: xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  • The service's own namespace, which is usually associated with the namespace prefix "tns" - (this namespace): xmlns:tns="http://yourDomain/yourService/serviceName"
  • The "target" namespace, which is generally identical to the "tns" one: targetNamespace="http://yourDomain/yourService/serviceName"

There may be many more than these (look at any Microsoft .Net service WSDL), but most services will define at least these ones as a minimum, although not always in exactly this form. In particular, the choice of namespace prefixes is arbitrary, so the base namespace might be specified as "xmlns:wsdl", rather than just "xmlns"; "xmlns:xs" is often seen as "xmlns:xsd"; "xmlns:soap" might be "xmlns:soap11" (in reference to SOAP 1.1) or many other variations - remember that it is the actual namespace URI which is being referenced that is important, not the prefix used to represent it in the document, which can be anything.

The "service" element

Although the last of the children of the <description> element, the service element is the natural starting point for human WSDL readers. There can be more than one service defined in a single WSDL document, which is sometimes sensible for describing different physical services which share the same logical definition (a service provider might provide the same service from a number of different network locations - i.e. servers - to provide redundancy, or multiple services might share some aspects, in particular data types, in common), however most commonly only a single service will be described.

As with serveral of the WSDL main elements, the service element can have a <documentation> element within it. In Visual DataFlex you can set this via the "psDocumentation" property of the Web Service object. It will also have a name attribute, which will be whatever you set the psServiceName property of your Web Service object to.

The crucial element within the service is the <port>. This defines an implementation of the service as a network resource and has a "binding" attribute which will point to a <binding> element (see below) in the same WSDL document (and hence will tend to have the namespace prefix "tns": this namespace). This will attribute will lead us on our trail, up the WSDL, to our next stop, the binding element.

While there are sometimes other protocols defined (HTTP, SMTP, FTP, etc.), the commonest by far is for SOAP, so within the <port> element it is common to find a <soap:address> element, specifying, via its "location" attribute, the actual URI through which the service can be invoked.

The "binding" element

The binding element is what joins the physical implementation of the service - a <port> element within the <service> element - to its logical (or abstract) definition, which is represented by the <portType> element (see below).

The binding element will have two attributes which effect this joining: its name attribute, which is what is pointed to by the binding attribute of the service "port" element above, and its type attribute which in turn points to a "portType" (again, usually defined within the same WSDL document and hence having a "tns" prefix).

Within the binding element there will be one or more protocol binding elements, the most common of which is the <soap:binding>. This will define the SOAP style attribute, either "rpc" or "document", and a transport element, set to a URI defining that, such as "http://schemas.xmlsoap.org/soap/http".

Following this there will be the <operation> elements, each with a name attribute (in Visual DataFlex this will be the name of the published Function or Procedure).

Each of these will contain first a operation protocol binding, such as <soap:binding> which will again define a style attribute and also a soapAction attribute; this latter will appear as the HTTP Header field "SOAPAction" in the messages sent to and from the operation (in Visual DataFlex services this is set to an empty string).

Following this there will be <input> and <output> elements for the operation, containing a definition of the way data is to be passed in the messages. Typically this will take the form of a <soap:body> element with a use attribute specifying either "literal" or "encoded. If an "encoded" usage is specified then an encodingStyle attribute may be present, pointing to a URI defining the style, such as "http://schemas.xmlsoap.org/soap/encoding/". There may also be a namespace attribute, for specifying a specific namespace for the operation. Additionally there may be a <soap:header> element, but discussion of this falls outside the scope of this article.

The "portType" element

The portType element is the abstract representation of the service and is identified by its name attribute (what the type attribute of a binding element points to).

It will contain a number of operation elements, one for each operation of the service.

Each operation may contain a documentation element, describing the operation (in Visual DataFlex you can set this through the "{ Description = }" meta-data tag that precedes your published Function or Procedure).

There will then be <input> and <output> elements, each of which will contain a message attribute, pointing to (the name attribute of) a message element (see below) which will hold the definition of that input or output message. Such message elements will usually appear within the same WSDL document and thus will commonly have the "tns" prefix.

The "message" element

The message elements define the structure of the data which will be passed as the contents to and from the service.

Each message element has a name attribute (which is what the message attributes of the portType input/output message elements was pointing to).

Typically the message element will then contain <part> element(s). In the case of document-style services there will only be one of these, as in document-style all the data tends to be sent (or received) as a single XML document (hence the name), however for RPC-style services there may be any number, with each corresponding to a parameter passed to, or returned from, the implementing function or procedure. Each part element will have a name attribute - in Document-style this is usually always "parameters", while in RPC-style it will be the name of the argument to the function. Finally there will either be a type attribute (RPC only) or an element attribute (RPC or Document). If a type attribute is used then it will define the primitive XML data type of the parameter. If an element attribute is used then it will refer to a data type (complex or otherwise) defined elsewhere - typically in the <types> element (see below) of the same WSDL document and hence will have the "tns" prefix.

The "types" element

The types element is optional, but is generally required for any non-trivial services, especially those of Document-style. There is only ever one types element in a WSDL document.

Within the types element there will be one or more <schema> elements within the "http://www.w3.org/2001/XMLSchema" namespace. Within these will be the definitions of all the data types used by the service, beyond the XML primitive types, and in fact in Document-style services even the most primitive data type (including none at all!) is generally referenced to a specific definition in a schema.

The topic of XML schema definitions is beyond the scope of this article however, so our investigation of the elements of WSDL, and their decomposition, must end there.

Example

To illustrate the above here is a sample of a very simple (it takes a single string as a parameter and returns another string) service WSDL: start from the service element at the bottom and work up through the various elements to the types definitions:

<?xml version="1.0" encoding="UTF-8" ?> 
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
             xmlns:xs="http://www.w3.org/2001/XMLSchema"
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
             xmlns:tns="http://unicorninterglobal.com/sample/"  --set from psServiceURI
             name="Hello" 
             targetNamespace="http://unicorninterglobal.com/sample/">  --set from psServiceURI
 
 <types>
    <xs:schema elementFormDefault="qualified" targetNamespace="http://unicorninterglobal.com/sample/">
      <xs:element name="SayHello">          --link from input message
        <xs:complexType>
          <xs:sequence>
            <xs:element name="sName" type="xs:string" />  --and in the end it is just a string!
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="SayHelloResponse">  --link from output message
        <xs:complexType>
          <xs:sequence>
            <xs:element name="SayHelloResult" type="xs:string" />  --and so it this one!
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>
  </types>

  <message name="SayHelloSoapRequest">                        --link from portType
    <part name="parameters" element="tns:SayHello" />         --link to type definition
  </message>

  <message name="SayHelloSoapResponse">                       --link from portType
    <part name="parameters" element="tns:SayHelloResponse" /> --link to type definition
  </message>

  <portType name="HelloSoapType">                    --link from binding
    <operation name="SayHello">
      <documentation>This operation says 'Hello!'</documentation> --set from { Description = "..."  } meta-data on function
      <input message="tns:SayHelloSoapRequest" />    --link to message
      <output message="tns:SayHelloSoapResponse" />  --link to message 
    </operation>
  </portType>

  <binding name="HelloSoapBinding" type="tns:HelloSoapType">   --links from service and to portType
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> 
    <operation name="SayHello">
      <soap:operation soapAction="" style="document" /> 
      <input>
        <soap:body use="literal" /> 
      </input>
      <output>
        <soap:body use="literal" />
      </output>
    </operation>
  </binding>

  <service name="Hello">
    <documentation>Sample documentation for the service</documentation>       --set from psDocumentation
      <port name="HelloSoap" binding="tns:HelloSoapBinding">                  --connects to the "binding" element
        <soap:address location="http://www.sample.com/services/Hello.wso" />  --service endpoint URI
      </port>
  </service>