I am finding it hard to overstress the importance of types in the WSDL framework. This is especially important to understand for Tcl programmers who rarely have to deal with types until some bug shows up and forces the issue. But the same can be said of programmers in general. Many many bugs and corresponding developer time can be traced to feeding the wrong data to a function. A Web Service essentially allows a remote user to invoke functions on a system with data of the user's choice. Even with the best of intentions, it is unwise to accept un-checked data from users.
Fortunately WSDL demands the use of XML Schema to define types. At first, XML Schema appears to be difficult and complicated. In actual fact, it is rather easy to explain and use. In explaining it here, I will introduce the expected API for defining types.
proc ::wsdl::types::newPrimitiveType {typeName code description} { namespace eval ::wsdl::tcl::$typeName [list variable description "$description"] proc ::wsdl::tcl::${typeName}::validate { value } $code }
The top level namespace is ::wsdl. This may change, for instance maybe ::twsdl would be better. Below that is the ::wsdl::tcl namespace. I am temporarily using this namespace as an indication that the type checking are based upon tcl types, and are not yet exactly the same as the definition given by XML Schema. Once we have a complete list of primitive types that match XML Schema types, we can move the primitive namespace to something else. However, it will still be possible to create derived types based upon the Tcl types, they will still be primitive in tWSDL, but will require the client to be the tWSDL client.
proc ::wsdl::types::addSimpleType {tns typeName {base "tcl::anySimpleType"} } { namespace eval ::wsdl::${tns}::${typeName} [list variable base "$base"] proc ::wsdl::${tns}::${typeName}::validate { value } " variable base if {\[::wsdl::\${base}::validate \$value]} { return 1} else { return 0}" }
This API also demonstrates that types have namespaces. (Note that this is different than a Tcl namespace, although we will use the type namespace name as the name of the Tcl namespace for the type.) The example API puts the type namespace as a child of the ::wsdl namespace. It might be necessary to create a separate toplevel for all types.
New simpleTypes can also be derived from other simpleTypes or primitive types. You derive a new simpleType by several means: one is by enumeration and the other is by pattern.
Here are example calls of both API:
::wsdl::types::restrictionByEnumeration::new "CreditCardTypeCode" "s:string" { "Visa" "Mastercard" "AmericanExpress" "Discover" "DinersClub" } ::wsdl::types::restrictionByPattern::new "guid" "s:string" \ {[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}}