The Web Service Description Language (WSDL) is a language for describing Web services. If we copy the emp.xquery to a folder where our Java servlet container is running (/employee-lookup, for example), we can use the following URL to access a WSDL document that describes the Web service that results from our XQuery:
http://examples.xquery.com/employee-lookup/WSDL
Using this URL, we can take a closer look at how our XQuery is described by the WSDL document. In particular, let's look at these:
Service Element
The service element — only one per WSDL document — is named after the query file name without its extension. The service contains two port definitions that always have the same name: SOAPPort and HTTPGETPort, respectively; one for SOAP over HTTP, one for HTTP GET.
<wsdl:service name="Service">
<wsdl:port binding="dd:SOAPBinding" name="SOAPPort">
<wsdlsoap:address
location="http://examples.xquery.com/employee-lookup/WSDL"/>
</wsdl:port>
<wsdl:port binding="dd:HTTPGETBinding" name="HTTPGETPort">
<http:address
location="http://examples.xquery.com/employee-lookup/WSDL"/>
</wsdl:port>
</wsdl:service>
Notice that the service address or end point is the same for both ports.
For each element wsdl:port under the element wsdl:service there is an attribute called binding=; the attribute value matches the value of attribute name= of one of the binding elements.
HTTPGETBinding
The HTTPGETBinding describes the HTTP verb (in this case it is GET), which operations are exposed, and how the input/output are encoded. The attribute location= in the element wsdl:operation is particularly important — it represents the query function to invoke in our query; in this case emp means the query body.
<wsdl:binding name="HTTPGETBinding" type="dd:HTTPGETPort">
<http:binding verb:"GET"/>
<wsdl:operation name="emp">
<http:operation location="/emp"/>
<wsdl:input>
<http:urlEncoded/>
</wsdl:input>
<wsdl:output>
<mime:mimeXML part="Body"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
SOAPBinding
The SOAPBinding (in the following code sample) describes which encoding style will be used by the service; the value can be either rpc or document (in our case it is always document). The style document is completely driven by the schema definition associated to the message, so the resulting XML fragment is more elegant. The style rpc assumes the creation of a wrapper element that matches the underlying function name to encapsulate the function arguments. The XML on the wire may look the same, but it is conceptually different.
Each wsdlsoap:operation defines the attribute soapAction= that, similar to the attribute location= in http:operation, represents the function name; soapAction= must be encoded as an HTTP header in the Web service request.
The attribute use= in the element wsdlsoap:body can be either literal or encoded. (In the generated WSDL it will be always literal, as suggested by the OASIS WS Basic Profile 1.0, to improve interoperability between different client implementations.) The message representation on the wire has the child element of the element wsdlsoap:body, which matches the global element defined in the XML Schema and is declared in the related message part.
The attribute type= in the element binding matches the attribute name= of one of the element portType. The element portType associates to each operation one message for the input and one for the output.
<wsdl:binding name="SOAPBinding" type="dd:SOAPPort">
<wsdlsoap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document"/>
<wsdl:operation name="emp">
<wsdlsoap:operation soapAction="emp.xquery" style="document"/>
<wsdl:input>
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
For each query function there is a pair of messages (input and output) for each binding (SOAPPort and HTTPGETPort). Having different messages for each binding allows, for instance, simple types like xs:string or xs:integer to be used for HTTP GET, which can be easily expressed inline as a URL.
<wsdl:portType name="SOAPPort">
<wsdl:operation name="emp">
<wsdl:input message="dd:empInputMsg"/>
<wsdl:output message="dd:OutputMsg"/>
<wsdl:fault name="nmtoken" message="dd:FaultMsg"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:portType name="HTTPGETPort">
<wsdl:operation name="emp">
<wsdl:input message="dd:empInputMsg"/>
<wsdl:output message="dd:OutputMsg"/>
<wsdl:fault name="nmtoken" message="dd:FaultMsg"/>
</wsdl:operation>
</wsdl:portType>
The element wsdl:message may have multiple sub-elements called wsdl:part; each part references either an XML Schema global type or global element. OASIS WS Basic Profile 1.0 suggests using only one part and a global element. To mimic the validation process against an XML Schema, the validation always starts from a global element — the document root.
<wsdl:message name="empInputMsg">
<wsdl:part name="parameters" element="dd:emp"/>
</wsdl:message>
<wsdl:message name="OutputMsg">
<wsdl:part name="Output" element="dd:Output"/>
</wsdl:message>
<wsdl:message name="FaultMsg"/>
Finally, the WSDL describes the element types where the XML Schema types are defined. For each message, the XML Schema defines two global elements – one for the input and one for the output.
<wsdl:types>
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.datadirect.com"
attributeFormDefault="unqualified"
elementFormDefault="qualified">
<xs:import schemaLocation="employee.xsd"
namespace="http://www.employee.com"/>
<xs:element name="emp">
<xs:complexType>
<xs:all>
<xs:element type="xs:string" name="id"/>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element type="xs:anyType" name="Output"/>
</xs:schema>
</wsdl:types>