While you were creating the virtual name for your Web service, the IIS Virtual Directory Manager created a WSDL file in the directory you specified for the virtual name. The WSDL file describes how to invoke your newly created Web service from another application and is a crucial piece of information for users of your Web service.
WSDL describes each method as a set of messages that the client and the server exchange. The WSDL file is an XML document that describes the methods of your Web service (in this example, the getOrderList stored procedure), including the names and types of parameters, the names and types of return values, and the URL you use to invoke the method. Web Listing 1 shows the WSDL that SQLXML 3.0 generated for the Web service you constructed. (To access the Web listing, enter InstantDoc ID 24910 at http://www.sqlmag.com and click Download the code.) Let's briefly look at the WSDL file so that you can get a basic understanding of how Web services work with SQLXML 3.0. (For detailed information about WSDL files, see the "Contents of the WSDL File" section in SQLXML 3.0 BOL.)
The WSDL file defines messages by using wsdl:message elements. Web Listing 1's example contains two messages: getOrderListIn and getOrderListOut. Each message has one message part corresponding to a complex XML that is specified using the wsdl:part subelement. Wsdl:part's element attribute refers to a complex type defined or referred to within the wsdl:types elements. SQLXML 3.0 defines the complex types by using standard XML Schema Definition (XSD) schemas. Notice in Web Listing 1 that the wsdl:types element contains several schema definitions. Only the last schema is specific to your Web service. All the other schemas defined in the wsdl:types element are part of every WSDL file that SQLXML 3.0 generates. These schemas contain common type definitions that SQLXML 3.0 uses to implement the Web service. Your Web service-specific schema includes these schemas by using xsd:import statements. For the getOrderList messages, the Web servicespecific schema defines two complex types: getOrderList and getOrderListResponse. These type definitions specify the XML content of the messages that pass between the client and the server within the SOAP protocol. The wsdl:operation subelement of the wsdl:portType element associates these messages with one of the Web service's methods. The wsdl:binding element associates each method specified by a wsdl:operation in the wsdl:portType element with an encoding of the I/O messages within the protocol. In this case, the getOrderList operation uses SOAP document encoding over HTTP. (For descriptions of the different binding types, see the WSDL specification at http://www.w3.org/TR/wsdl.) Finally, the wsdl:service element associates the methods defined within wsdl:portType and the bindings in the wsdl:binding element with the URL that accepts messages and executes the Web service's methods.
By interpreting the WSDL, a client can send the appropriately formatted SOAP messages to SQLXML 3.0, which in turn interprets the SOAP message and invokes the stored procedure configured for the virtual name. You might notice the OrderStatus.ssc SOAP service configuration (SSC) file in the same directory as the WSDL file. OrderStatus.ssc, an XML file containing configuration data that SQLXML 3.0 generated, holds data about the stored procedures that make up your Web service's methods. SQLXML 3.0 uses the data from this file to correctly call a stored procedure when it receives a SOAP request. OrderStatus.ssc also provides configuration data that specifies how SQLXML 3.0 formats the stored procedure's output parameters into a SOAP response message that is returned to the client.
Using a Web service could be tedious if you needed to write code directly in your program to interpret the WSDL file. Thankfully, Microsoft provides the SOAP Toolkit 2.0, which reads a WSDL file and provides an automation object that supports the methods defined within the WSDL file. Web Listing 2 shows a VBScript example that uses the SOAP Toolkit to invoke the getOrderList method on the Web service you just created. First, the code uses the mssoapinit method to create the SoapClient object and read the WSDL file from SQLXML 3.0. The method takes three parameters: a URL for the WSDL, the service name to use within the WSDL file, and a port to connect to the Web service (also specified in the WSDL file). Notice that the URL specifies the virtual directory and virtual name that you configured in the previous steps as well as a wsdl parameter. The wsdl parameter requests the WSDL for the Web service from SQLXML 3.0. The SoapClient object parses the WSDL (remember, the WSDL is in XML format), interprets the content, then dynamically provides getOrderList as a method of the SoapClient object.
Exposing methods dynamically on the SoapClient object lets programmers invoke Web services in the same way you call a method on a local object. The method returns an object that provides IXMLDOMNodeListan interface from the XML Document Object Model (DOM)to access a list of XML elements. The code assigns the interface to the xmlnodelist variable and uses the interface to access the returned data. If the stored procedure returns only one value with a simple type (e.g., the order count) instead of a result set, the SoapClient object returns the value directly to a variable within your script.
Web services provide a powerful new paradigm for implementing client/server processing both within and between enterprises. Admittedly, this column's example would be more complete if it showed how the customer's order system requested the data automatically. Nevertheless, the example shows how you can easily build a Web service by using SQLXML 3.0. You can apply this technology in many other scenarios. For example, you can use Web services to replace direct execution of stored procedures from your Web serversor from any HTML, Active Server Pages (ASP), or JavaServer Pages (JSP) application. By using SQLXML 3.0's Web services, you can gain the advantages of a loosely coupled interface and extensibility of both the interface and the data you return.