ToC | DocOverview | CGDoc | RelNotes | FAQ | Index | PermutedIndex
| Allegro CL version 9.0 Moderate update since 9.0 release. 8.2 version

# A SOAP 1.1 API for Allegro CL

This document contains the following sections:

1.0 Preface
2.0 Introduction
3.0 A Simple Client Example
4.0 Components of the API
5.0 Element Definition
6.0 Type Definition
6.1 Built-in Schema Types
7.0 Making a Client Call
8.0 SOAP Server Components
8.1 The SOAP Network Server
8.2 Exporting Methods
8.3 Controlling Access to Methods
8.4 Defining SOAP Methods
9.0 Programming Notes
9.1 Multiple Threads
9.2 Connector Class Hierarchy
9.3 When things go wrong - debugging SOAP interfaces
9.4 I18N Issues
10.0 WSDL Support
10.1 Limitations in WSDL support
10.2 WSDL Functions and Variables
10.3 Namespaces and Packages
10.3.1 Some important namespaces and packages
10.3.2 Namespace Definition Operators
10.3.3 Deducing the namespaces used in a WSDL file
10.4 Mapping SOAP Structures to CLOS classes
10.4.1 Generated Classes
10.4.2 Generated Accessors
10.4.3 Generated Constructors, Decoders, and Encoders
10.4.4 Call Wrapper Methods
10.4.5 Mapping SOAP Names to Lisp Names
10.5 How to generate a SOAP client interface from a WSDL definition
10.5.1 Combining Several WSDL Definitions in one Lisp Image
10.6 Customizing Generated Code
11.0 Headers
12.0 Faults and Errors
13.0 Index

## 1.0 Preface

An update released in late February, 2006, makes minor changes and corrections to the update to 7.0 made earlier in the month and to the SOAP released with 8.0. One documentation correction should be noted: the default for the :nillable option (to operators like soap-message-client) is `:ignore` (making it compatible with earlier versions). The earlier documentation update incorrectly said the default was `:accept`.

This document describes an implementation of the Allegro CL SOAP API. There are still pieces of the Allegro CL/SOAP implementation to be completed. These will be released when they are ready.

- The implementation is incomplete in a few areas. Missing features do not indicate a decision to not support, but should be reported since we may have failed to note the omission.
- The specifications are believed to be stable but may change as implementation proceeds and feedback is incorporated. (This means that the Final release may not be backward compatible with this one.)

The Implementation Plan for the Allegro/SOAP API is as follows.

- Client API with built-in data types (described in this document)
- Server API with built-in data types (described in this document)
- WSDL 1.1 support (described in this document)
- WSDL generation (described in this document)
- Event-driven (SAX-like) API (to be implemented)
- SOAP 1.2 (to be implemented)
- WSDL 1.2 (to be implemented)

## 2.0 Introduction

The Allegro CL SOAP module requires the SAX parser (:sax) and the AllegroServe (:aserve) modules. These modules are loaded automatically when the SOAP module is loaded.

You load the SOAP API into a running lisp with the following call to require:

    (require :soap)

All the symbols in the SOAP API are exported from the `net.xmp.soap` package.

There is a SOAP client example in examples/soap/soapex.cl. There is a SOAP server example in examples/soap/soapval1.cl.

The letters xmp stand for XML Message Protocol. The XMP component implements a separately documented API that is used as a basis for the SOAP implementation and for other XML-based message protocols such as XMLRPC.

Users may find it more convenient to try the SOAP examples in a Modern (case-sensitive) Allegro CL image. Since case in SOAP symbols is significant, SOAP symbols typically have mixed case print names. Modern mode handles mixed case names without special effort. If you use an ANSI (case-insensitive) Allegro CL image, SOAP symbols need to be wrapped in vertical bar escapes (as is done in the Simple Example just below) in order to preserve their mixed-case print names.

There is another example in the file [Allegro directory]/examples/soap/bignum-server.cl.

## 3.0 A Simple Client Example

This simple example shows how to access a public SOAP server that returns currency conversion rates. (See also the file examples/soap/soapex.cl.)

This example accesses an external public SOAP server which was available at the time this document was written. This specific example may not produce the described result at other times and places.

The symbols in the "urn:xmethods-CurrencyExchange" namespace are exported from a Lisp package created for this purpose.

    (require :soap)
    (use-package :net.xmp.soap)

    ;;  This form ensures that XSD is a nickname of the NET.XMP.SCHEMA
    ;;  package:
    (defpackage :net.xmp.schema (:use) (:nicknames :xs :xsd))

    (defpackage :conv (:use) (:export "getRate"))

We define a function to send the message and decode the reply:

    (defun convert (&optional (country1 "Canada") (country2 "USA"))
      (let ((conn (soap-message-client
             :lisp-package :keyword
                    :url "http://services.xmethods.net:80/soap")))
        (call-soap-method
         conn
         '(:element
           conv:|getRate|
           (:complex (:seq (:element "country1" xsd:|string|)
                           (:element "country2" xsd:|string|)
                           )
                    :action ""
                    :namespaces
                    (nil (:conv "tns" "urn:xmethods-CurrencyExchange"))
                    ))
         :|country1| country1 :|country2| country2
         )))

The main element of the message is defined (in line) as a complex type composed of a sequence of two elements "country1" and "country2". The content of each of these elements is declared to be a string. The information needed to create the element definitions must be obtained from the server documentation, often in the form of a WSDL file.

We try the function (we got the response indicated when this example was run but this is an external service and it may not work as indicated when you try it, either because of a temporary glitch or a permanent problem or change):

    cl-user(4): (convert)
    (conv::getRateResponse (:Result 0.8188))
    nil

The result message is returned as a nested list of association lists where element name is the key and element content is the value.

## 4.0 Components of the API

The client API encodes Lisp data into a SOAP message and transmits the encoded HTTP message to the server. The reply from the server is another HTTP message that is decoded into Lisp data returned to the caller. SOAP messages may be exchanges with the HTTP protocol, or with the HTTPS protocol when SSL security is needed. We use the term HTTP protocol in this document to refer to both.

The server API defines Lisp functions that are called when specified messages are sent to the server. The messages arrive as encoded HTTP text and the value returned by the function is sent as an encoded HTTP reply message.

The XML elements in both outgoing and incoming messages must be defined in order to specify the required encoding and decoding behaviors.

## 5.0 Element Definition

An element definition specifies how an element should be encoded in a message to a server and how it can be decoded in a reply message.

An element definition can appear as a component in a Lisp list structure that describes a compound XML element:

    element-def -> (:element elt-name-spec type-spec [:nillable t])

The `nillable` option, when non-`nil`, adds the "xsd:nillable='true'" attribute to the element.

An element definition can also be created with a call to define-soap-element:

### define-soap-element

### Generic Function

#### Package: net.xmp.soap

Arguments: conn elt-name-spec type-spec &rest def-options &key (redef :warn) nillable &allow-other-keys

After a call to define-soap-element, any of the names listed in the elt-name-spec may be used to denote the defined element.

The conn argument may be `nil` but can also be used to define behavior specific to a particular class of connections.

The elt-name-spec argument specifies one or more names by which the element can be identified. It is described below.

The type-spec argument may be the name of a separately defined SOAP type, the name of a built-in SOAP type or an anonymous type definition as defined in the next section. When type-spec is `nil`, the named definition is removed.

The redef option controls the behavior when a definition already exists. The possible values are:

- `nil` - silently replace the existing definition
- `:warn` - print a warning if a definition exists and is not equal to the new definition
- `t` - signal an error (instead of a warning)

The nillable option, when non-`nil`, marks the element as nillable. When an element is nillable, instances of the element may appear in a document with an empty content and a property "xsi:nil='true'" - in this case, treat the element as if it were not there.

When the element definition is output to a WSDL Schema definition, the element is tagged with the attribute "xsd:nillable='true'".

Additional keyword arguments are saved as options in the element definition.

An `elt-name-spec` is defined as follows:

    elt-name-spec -> symbol | string
                  -> ( { symbol | string | (:any-case string) }... )

When a SOAP message is created, the first (or only) name in `elt-name-spec` determines the name included in the message. The components of an `elt-name-spec` are:

    string --> unqualified QName
    symbol --> 1. If the symbol-package of the symbol has been
                     associated with a namespace
    	        AND
    	         the namespace is included in the current context,
    	        THEN
    	         the qualified QName is included in the message.
    	  2. OTHERWISE the symbol name is included as an unqualified QName.
    (:any-case string) --> treated like string above

When a SOAP message is decoded, any one of the names in the `elt-name-spec` is accepted as a name for this element.

    string --> accept any string= QName in any namespace
    symbol --> accept the EQ symbol
    (:any-case string) --> accept any string-equal QName in any namespace

## 6.0 Type Definition

A type definition specifies the structure, content and attributes of an XML element. A type definition also specifies the encoding from Lisp to XML and the decoding from XML to Lisp.

A type definition can appear as a component in a Lisp list structure that describes a compound XML element:

    type-def -> (:simple simple-type-spec simple-option... )
             -> (:array type-spec array-option... )
             -> (:complex complex-def complex-option... )

A type definition can also be created with a call to define-soap-type:

### define-soap-type

### Function

#### Package: net.xmp.soap

Arguments: conn name type-def &key (redef :warn) &allow-other-keys

Once defined, a type name may be used in other element or type definitions. When type-def is `nil`, the named definition is removed.

Additional keyword arguments are saved as options in the element definition.

    simple-type-spec -> nil | type-name
           type-spec -> type-name | type-def

     complex-def -> (collector complex-part ...)
       collector -> :seq    ;; zero or one of each part in specified sequence
                 -> :seq*   ;; zero or more of each part in specified sequence
                 -> :seq+   ;; one or more of each part in specified sequence
                 -> :seq1   ;; exactly one of each part in specified sequence
                 -> :set    ;; zero or one of each part in any sequence
                 -> :set*
                 -> :set+
                 -> :set1
                 -> :or     ;; exactly one of the parts

The components of :seq :seq* :seq1 and :seq+ must be ordered as specified.

The components of :set :set* :set1 and :set+ may appear in any order.

When a complex element is encoded, the sub-elements are always encoded in the order listed in the definition.

    complex-part -> element-spec | complex-def
    element-spec -> element-name | (:any} | element-def

When a complex-part denotes a sequence of elements the sequence is spliced into the sequence containing the complex-part.

Sub-element definitions enter only through an element-def with a :complex or :array type-def.

#### Options on :complex type-def:

- `:action string` - this option is needed on the top-level element of a message to specify the content of the SOAPAction HTTP header in the request to the server.

#### Options on any type-def:

Option Name | Possible Values | Description
:namespaces | The name of a namespace map or a list containing an explicit namespace map. | This option may be present on any element. The default-urn is encoded as the "xmlns=" attribute in the element and the other components are encoded as "xmlns:prefix=" attributes. Namespace definitions are inherited by nested sub-elements, and obey the namespace scoping and masking conventions of XML. Symbols in the specified Lisp packages are encoded as qualified QName strings with the appropriate prefix.
:attributes | A property list | This option may be present on any element. When present, this option is encoded as a sequence of attributes "property-name=property-value".
:must-understand | nil or non-nil | This option is recognized only on the type-def of a top-level element sent as a Header element in a message. If non-`nil` then a "mustUnderstand" attribute with value "1" is included. If `nil`, then a "mustUnderstand" attribute with value "0" is included.
:encoding | URLlist | A string consisting of one or more URLs separated by spaces. Sent as the `SOAP-ENV:encodingStyle` attribute in the element.
:computed-attributes | function-name | The named function is called with two arguments `(conn element-name)` and is expected to return a property-list of the form `(attr-name value ...)` to be added to the attributes of the element. When encoding a mesage sent with call-soap-method, the function is called in the dynamic environment of the call to call-soap-method. When encoding a message returned from a server method, there is no dynamic environment relevant to the application. When encoding a message with soap-encode-object, the function is called in the dynamic environment of the call to soap-encode-object. (Use soap-encode-object when computing a method return if dynamic environment is relevant.)
:send-type | `nil`, `t`, or a string or symbol that names a Schema type | This option may be present on any element. A non-`nil` value specifie that the "xsi:type" attribute should be added to the element instance in the SOAP message. If the value of the :send-type option is `t`, then the type of the element must be a named type; the name of the element type is sent as the value of the "xsi:type" attribute. If the value of the :send-type option is a string or a symbol other than `t`, then the value of the option is sent as the value of the "xsi:type" attribute. If the value of the :send-type option is `nil`, then the "xsi:type" attribute is omitted from the outgoing message. If the option is not specified, then the behavior is controlled by the value of the :send-type initarg to soap-message-client or soap-message-server.

#### Options on :array type-def:

Option Name | Possible Values | Description
:length | A single integer or a list of integers | This option specifies the dimensions of an array. A single integer denotes a 1-dimensional array of that length. A list of n integers denotes an n-dimensional array.
:send-atype | A type name or a string of the form "type[]" or "type[15,17]". | Send a `enc:|arrayType|` attribute with `type-name` as the value.
:send-asize | `nil`, a number, some other value, `t` | If non-`nil`, include an array size in arrayType. If the value is a number, send that number. If value is another non-`nil` value, then the length of the data determines the actual dimension sent in the message. If this option is non-`nil`, then the `:send-atype` option must not include any dimension values, i.e. in a form such as "type[15,17]". A list of integers should send that list as dimensions but that is NOT IMPLEMENTED.
:array-item | A list like `([array-item-prop-name array-item-prop-val] ...)` | This option provides additional detail about how an array should be encoded. The possibilities for `array-item-prop-name` and `array-item-prop-val` are:
    array-item-prop-name:   array-item-prop-val:

       :element                element-spec
       :send-type              boolean
       :attributes             property-list

       :argument               arg-spec

                                 This option specifies how array
                                 elements are passed to the encoding
                                 functions.  The argument is a list
                                 of element data items as follows:

                                 arg-spec:              data item:

                                 :element-and-arg       (element-spec data)
                                 :type-and-arg          (type-spec data)
                                 :attributes-and-arg    (property-list data)
                                 :arg-only              data
                                 nil                    data

## 6.1 Built-in Schema Types

The package qualifier `xsd` is a nickname for the `net.xml.schema` package. You must have evaluated `(defpackage :net.xmp.schema (:use) (:nicknames :xs :xsd))` in order for the nickname to be valid. Otherwise, replace `xsd` with `net.xmp.schema` in the lists below.

The package qualifier `enc` is a nickname for the net.xml.soap.encoding package. You must have evaluated `(defpackage :net.xmp.soap.encoding (:use) (:nicknames :enc))` in order for the nickname to be valid. Otherwise, replace `enc` with `net.xmp.soap.encoding` in the lists below.

The following Schema and SOAP Encoding types have definitions built into the SOAP module.

             Schema and
            SOAP Encoding        Decoded to            Encoded from
               Type              Lisp type              Lisp type

          enc:|QName|
          xsd:|QName|              symbol                  symbol

         enc:|decimal|
         xsd:|decimal|         integer or ratio            number

           enc:|long|
           xsd:|long|              integer                 number in range

      enc:|unsignedLong|
      xsd:|unsignedLong|           integer                 number in range

           enc:|int|
           xsd:|int|               integer                 number in range

       enc:|unsignedInt|
       xsd:|unsignedInt|           integer                 number in range

         enc:|integer|
         xsd:|integer|             integer                 number

      enc:|nonPositiveInteger|
      xsd:|nonPositiveInteger|     integer                 number in range

      enc:|nonNegativeInteger|
      xsd:|nonNegativeInteger|     integer                 number in range

      enc:|negativeInteger|
      xsd:|negativeInteger|        integer                 number in range

      enc:|positiveInteger|
      xsd:|positiveInteger|        integer                 number in range

           enc:|short|
           xsd:|short|             integer                 number in range

           enc:|byte|
           xsd:|byte|              integer                 number in range

      enc:|unsignedShort|
      xsd:|unsignedShort|          integer                 number in range

      enc:|unsignedByte|
      xsd:|unsignedByte|           integer                 number in range

       enc:|boolean|
       xsd:|boolean|              t or nil                    any

          enc:|float|
          xsd:|float|             double-float                 number

          enc:|double|
          xsd:|double|            double-float                 number

        enc:|base64|
       enc:|base64Binary|
       xsd:|base64Binary|          string                      string

All the following types are decoded to a Lisp string and any Lisp value is encoded to a string in the outgoing message:

      enc:|string| enc:|duration| enc:|dateTime| enc:|time| enc:|date|
      enc:|gYearMonth| enc:|gYear| enc:|gMonthDay| enc:|gDay|
      enc:|gMonth| enc:|anyURI| enc:|NOTATION| enc:|token|
      enc:|language| enc:|IDREFS| enc:|ENTITIES| enc:|NMTOKEN|
      enc:|NMTOKENS| enc:|Name| enc:|NCName| enc:|ID| enc:|IDREF|
      enc:|ENTITY| enc:|normalizedString| xsd:|normalizedString|
      xsd:|duration| xsd:|dateTime| xsd:|time| xsd:|date|
      xsd:|gYearMonth| xsd:|gYear| xsd:|gMonthDay| xsd:|gDay|
      xsd:|gMonth| xsd:|anyURI| xsd:|NOTATION| xsd:|token|
      xsd:|language| xsd:|Name| xsd:|NMTOKEN| xsd:|NCName|
      xsd:|NMTOKENS| xsd:|ID| xsd:|IDREF| xsd:|ENTITY| xsd:|IDREFS|
      xsd:|ENTITIES|

      xsd:|string|

## 7.0 Making a Client Call

To make a client call, an application must create a connection instance with a call to soap-message-client.

A SOAP service available via HTTP is located with a URI that has several components:

- The protocol component is always HTTP
- The host and port components identify the network location of the server
- The path component identifies the SOAP server among the services reached through the HTTP server (i.e. the same HTTP server may be providing web pages from files, messages from servlets, and many other web services)
- In a client call, all these components are specified as part of the server URI. In a server definition, the host is frequently unspecified, the port may be specified in the :start argument list, and the path is specified separately in the :start argument list.

A SOAP service that requires HTTPS is simply accessed with a URL that starts with "https://".

Within the HTTP request that carries the SOAP message there are HTTP headers that can be treated as attributes of the HTTP request. The `soapAction` header may be used by a specific SOAP server to recognize or to dispatch a message.

The entire pattern used to identify a SOAP method to be called consists of these components:

- The SOAP method - this is the element name of the main (and only) XML element in the SOAP message body element.
- The soapAction header string
- The element names of the immediate sub-elements of the SOAP method element.

### soap-message-client

### Function

#### Package: net.xmp.soap

Arguments: &rest options

The options (keywords) and their values are (note that a value must be supplied for `:url`):

- `:url url-of-soap-server`: this argument is required since there can be no reasonable default.
- `:lisp-package package-or-name`. This option specifies the package where unqualified SOAP names are interned as Lisp symbols. The default is `net.xmp.soap.none`.
- `:must-understand flag`, `flag` can be `:strict`, `:warn`, or `nil`. The default is `:warn`.
- `:encoding string`, sent out as encodingStyle attribute. URIs separated by spaces, most specific first. The default is "http://schemas.xmlsoap.org/soap/encoding/".
- `:actor string`, the default is "http://schemas.xmlsoap.org/soap/actor/next".
- `:start list`, a list of additional arguments to do-http-request. The following keywords are used by the SOAP module internals and should not appear in the start argument: `:method`, `:protocol`, `:content-type`, `:content`, `:user-agent`, `:headers`, `:external-format`. The most likely user addition in this argument is `:proxy` to specify a proxy server.
- `:null-element value`: this argument specifies the behavior when the content of an element is specified as `nil`. value can be `:empty`, in which case an empty element is included in the message; or `:default-value` (which is the default if no value is specified), in which case an element with a default null content is included in the message. For numeric element types the default value is zero. Other possible values are:
  - `:nilled`: send an empty element with the attribute "xsi:nil='true'"
  - `:nilled-or-default`: if the element is defined with the nillable option `t` then like `:nilled` otherwise, send an element with a default content.
  - `:nilled-or-empty`: if the element is defined with the nillable option `t` then like `:nilled` otherwise, send an empty element.
  - `:nilled-or-none`: if the element is defined with the nillable option `t` then like `:nilled` otherwise, send nothing.
  - `:none`: do not include this element in the message.
- `:empty-element value`: this argument specifies how an empty message element is decoded into a Lisp value. If value is `:default-value` (which is the default if no value is specified), a suitable Lisp value is returned. For numeric element types this value is zero and for string types it is the empty string. If value is `nil`, the Lisp value is `nil`.
- `:decode-flag flag`: the flag argument may be `:strict`, `:warn`, or `nil`. When `:strict` is specified, all elements in a reply message must be defined, otherwise an error is signaled. When `:warn` is specified, undefined elements are accepted with a warning message. When `nil` is specified, all elements are accepted silently. The default is `:warn`.
- `:message-dns namespace-map`: the value of this option is a namespace map that is combined with the base-dns namespace map to form the full space map for each message sent or received through this connection. The default value is `nil`. In a typical application, the standard SOAP and Schema namespaces are specified in the :base-dns option and any additional namespaces specific to the application are declared in the :message-dns option.
- `:base-dns namespace-map`: this argument specifies the namespace map for the standard and required namespaces. The default value is `:soap`.
- `:trim-whitespace t-nil-or-string`: this argument determines the handling of the textual content of a SOAP message element. The value may be `nil`, `t` (the default), or a string. When `nil` is specified, then the content is not modified. When a string is specified, then any leading or trailing characters mentioned in the string are deleted from the element content. When `t` is specified, the characters #\return #\space #\tab #\newline are deleted from the beginning and end of the element content.
- `:body-form value`: this argument describes the SOAP Body element.

  The value `:one` (the default) specifies that the SOAP Body consists of exactly one element. In this case, the value of call-soap-method is the representation of the one and only element in the reply.

  The value `:many` specifies that the SOAP body may contain any number of elements. In this case, the value of call-soap-method is a list of all the elements in the SOAP body. This value must be specified if the SOAP reply message makes use of the multiRef feature.

- `:nillable value`: the value of this option specifies how element instances with an attribute "xsi:nil='true'" are handled. The possible values are:
  - `:ignore`: (the default, for compatibility with previous versions of the SOAP module) "xsi:nil" attributes are ignored. All elements will appear in the message returned to or passed to the application.
  - `:accept`, if an element appears with a "xsi:nil='true'" attribute and an empty content, then the element is not included in the message returned to or passed to the application.
  - `:strict`: the behavior is controlled by the element declaration. If the element is declared with a ":nillable t" option, then, if the element appears with a "xsi:nil='true'" attribute and an empty content, then the element is not included in the message returned to or passed to the application.
- `:send-type t-or-nil-or-other`: the value of this option controls the sending of a "xsi:type" attribute in outgoing SOAP messages. A value of `nil` suppresses the "xsi:type" attribute . A value of `t` causes an "xsi:type" attribute to be sent for any element with a named type definition. The value of the attribute is the name of the element type.

  The value of the option may also be a string or a symbol other than `t`; in this case, the value of the option is the value of the "xsi:type" attribute sent with any element that does not have an explicit :send-type option specified in the element or type definition.

- message-init value: this option specifies the storage strategy used when collecting SOAP messages. Since the SOAP specification requires the message length to be included in the SOAP message header, the SOAP module must collect the entire message before sending it. Since this may require an indefinite amount of storage, we use an adjustable array.

  The default setting of 500 starts with an initial array of 500 characters, extended as needed using the ACL default vector-push-extend strategy (ie double the array size).

  If the message-init argument is specified as a positive integer, it specifies a different inital array size, and the default extension strategy.

  If the message-init argument is a list, the first element must be a positive integer that specifies the inital array size. The second element, if present specifies an array extension strategy. A positive integer causes the array to be extended by that amount over what is immediately needed. A real number less than 1.0 causes growth by the specified fraction over the current size. A real number greater than or equal to 1.0 causes growth by the specified ratio.

The following keyword options have defaults which suffice in most normal situations, but different values may be specified in special situations:

- `:xml-leader string` - The default value is "xml version='1.0'" This value is inserted in the "<?xml >" declaration at the beginning of the SOAP message.
- `:xml-encoding value` - The default is `nil`. This argument specifies the encoding used for the SOAP message. The value may be the name of a Lisp external format, or a list of the form `(lname ename)` where `lname` is the Lisp name of the external format and `ename` is the name that should be shown as the encoding name in the "<?xml >" declaration.
- `:http-method value` - The default is `:post`. The other possible value is `:get`. (See the documentation for AllegroServe, in aserve/aserve.html.)
- `:http-protocol value` - The default is `:http/1.0`. The other possible value is `:http/1.1`. (See the documentation for AllegroServe, in aserve/aserve.html.)
- `:content-type value` - The default is "text/xml". This value is used as the `:content-type` argument to do-http-request. (See the documentation for AllegroServe, in aserve/aserve.html.)
- `:http-agent value` - The default is `nil`. This value is used as the `:user-agent` argument to do-http-request. (See the documentation for AllegroServe, in aserve/aserve.html.)
- `:http-host value` - The default is `nil`. This value is sent as the "Host" HTTP header. (See the documentation for AllegroServe, in aserve/aserve.html.)
- `:http-headers value` - The default is `nil`. This argument specifies any additional HTTP headers to be added to the SOAP message.

### call-soap-method

### Generic Function

#### Package: net.xmp.soap

Arguments: conn method &rest args

The conn argument is an instance of `soap-client-connector`.

The method argument determines the form of the SOAP message, and the remaining arguments (args) supply the data for the content of the message.

The method argument may be a string or symbol that denotes a SOAP element defined with define-soap-element. In this case, the Schema type of the element determines how the remaining arguments are interpreted. The table below shows the possible cases. The top-level element in the message is the element specified in the method argument. The contained sub-elements are built from the remaining arguments.

The method argument may be a list containing an explicit element definition, In this case, again, the type of the element determines how the remaining arguments are interpreted. The table below shows the possible cases. The top-level element in the message is the element specified in the method argument. The contained sub-elements are built from the remaining arguments.

The method argument may also be a symbol that denotes a complex SOAP type defined with define-soap-type, or a list containing an explicit type-def. In this case, the specified type determines how the remaining arguments are interpreted. The table below shows the possible cases. The top-level elements in the SOAP message are the immediate components of the complex type.

Type in method argument | Suitable Lisp Value
`:complex` | name value ... where each name occurs as a top-level element in the complex def.
`:array` | A sequence of items, each suitable as an array element.
`:simple` | A single value or a sequence of values.

The outgoing message includes any headers that have been added to the connector with soap-add-header (described below).

The function returns two values, the contents of the SOAP Body element, and a list of SOAP Header elements. The form of the body contents depends on the value of the `:body-form` option. If the option is `:one`, then the value is an LXML representation of the one and only element in the SOAP Body element. If the option is `:many`, then the value is a list of LXML forms that represent all the elements in the SOAP Body element.

If the call returns a SOAP Fault, then an error of type `soap-client-fault` or `soap-server-fault` is signaled.

### Examples

#### Example 1

In this example, we call a method with one argument declared as a simple element containing a string value. We use strings for all the element names because the server does not expect qualified XML names.

    (define-soap-element nil "simpleStructReturnTest"
      '(:complex (:seq (:element "myNumber" (:simple enc:|int|)))))

In the call to call-soap-method, the method argument is "simpleStructReturnTest". The remaining arguments are "myNumber", the name of the one element in the "simpleStructReturnTest" message; and 123, the value or content of the element.

#### Example 2

In this example, the SOAP method expects one argument declared as a complex element with 3 sub-elements.

    ;;  This example cannot be simply cut and pasted into a running
    ;;  Lisp because the server for the service is imaginary.
    ;;  Instead, this example is intended to show what
    ;;  a call might look like.
    (define-soap-element nil "easyStructTest"
      '(:complex
        (:seq
         (:element
          "stooges"
          (:complex
           (:set
    	(:element "moe" enc:|int|)
    	(:element "larry" enc:|int|)
    	(:element "curly" enc:|int|)))))))

    (call-soap-method client "easyStructTest" "stooges" (list "moe" 1 "larry" 2 "curly" 3))

In the call to call-soap-method, the method argument is "easyStructTest". The remaining arguments are "stooges", the name of the one element in the "easyStructTest" message; and the list `(list "moe" 1 "larry" 2 "curly" 3)`, the value or content of the element. The value in this case is a list because the "stooges" element has a complex content that consists of several elements. The list provides the names and values of the sub-elements.

#### Example 3

In this example, the SOAP method expects one argument declared as an array of elements. The Lisp argument corresponding to the "myArray" element is a list of strings. Each string in the list is encoded as an array element with the default element name "item".

    ;;  This example cannot be simply cut and pasted into a running
    ;;  Lisp because the server for the service is imaginary.
    ;;  Instead, this example is intended to show what
    ;;  a call might look like.
    (define-soap-element nil "moderateSizeArrayCheck"
      '(:complex (:seq (:element "myArray" (:array xsd:|string|)))))

    (call-soap-method client "myArray" (list "a" "b" "c" "d"))

To specify more precisely the layout of an array we could say

    ;;  This example cannot be simply cut and pasted into a running
    ;;  Lisp because the server for the service is imaginary.
    ;;  Instead, this example is intended to show what
    ;;  a call might look like.
    (define-soap-element nil "moderateSizeArrayCheck"
      '(:complex (:seq (:element "myArray" (:array xsd:|ur-type|
                                                   :array-item
                                                   (:element "myArrayElement"
                                                    :send-type t
                                                    :argument :type-and-arg))))))

In this case each array element in Lisp must be specified as a list where the first element is the SOAP type of the encoding and the second is the Lisp value to be encoded. Each array element will be encoded as an element named "myArrayElement" and the type will be encoded as a `xsd:|type|` attribute. (`xsd` is a nickname for the `net.xml.schema` package. You must have evaluated `(defpackage :net.xml.schema (:use) (:nicknames :xsd :xs))` for the nickname to be valid. Otherwise replace `xsd` with `net.xml.schema` in the example below.)

The method argument in this case is "moderateSizeArrayCheck". The remaining arguments are "myArray", the name of the one element in the "moderateSizeArrayCheck" message; and the list ((:xsd:|string| "a") (xsd:|int| 17)), which represents the two array elements. Each element in the list is represented by a list of the type and the value of the element.

#### Example 4

If the SOAP message must be composed of several top-level elements, then the method argument would be of the form:

      '(:complex (:seq element1 element2 element3))

and the remaining arguments would be

       'element1 data-for-element1 'element2 data-for-element2
       'element3 data-for-element3

The format of each of the data arguments is determined by the type of the corresponding element.

## 8.0 SOAP Server Components

A SOAP server exports methods that may be called from remote clients through a network interface. The network interface in this implementation is an AllegroServe HTTP server. A method is exported by specifying a SOAP element pattern and a Lisp function. When the specified message is received by the network server, the Lisp function is called. The arguments to the Lisp function are the decoded sub-elements of the message. The result returned by the Lisp function is encoded and sent as the reply message.

## 8.1 The SOAP Network Server

A SOAP network interface is established with a call to soap-message-server.

### soap-message-server

### Function

#### Package: net.xmp.soap

Arguments: &key start enable publish class name service-name url port-name binding-name action lisp-package message-dns base-dns must-understand decode-flag encoding actor trim-whitespace body-form send-type nillable message-init &allow-other-keys

The function returns an instance of `soap-server-connector`. This instance is an argument to most of the other API functions.

The arguments are:

- start: A list of arguments to pass to the function that starts the http server. Currently this is net.aserve:start (but may vary).
- enable: if `nil`, take no action. If `:start`, start the default http server and enable the SOAP server. If `:start-new`, start a separate http server and enable the SOAP server. If any other non-`nil` value, enable the SOAP server (this option assumes that the http server was started by some other means). The default is `:start`.
- publish: A list of arguments passed to the function that enables the SOAP server. Currently this is net.aserve:publish (but may vary); If the path argument is missing, `:path "/SOAP"` is added. The function and content-type arguments are not allowed in this list.
- class: The class of the server instance returned by this function. The default is `soap-aserve-server-string-in-out-connector`.
- name, service-name, url, port-name, binding-name: these arguments are used when writing a WSDL definition file. name should be a string or symbol that names the WSDL definition; it defaults to "SOAPServer". service-name should be a string or symbol that names the service; it defaults to "SSSServiceNNN". url should be a string that contains the URL used to reach this service; it defaults to "???". port-name should be a string or symbol that names the port definition; it defaults to "SOAPPortNNN". binding-name should be a string or symbol that names the SOAP binding of the service; it defaults to "SOAPBindingNNN".
- null-element: this argument specifies the behavior when the Lisp value of an element is `nil`. See the description of the argument of the same name for soap-message-client.
- empty-element: see the description of the argument of the same name for soap-message-client.
- trim-whitespace: see the description of the argument of the same name for soap-message-client.
- body-form: this argument describes the SOAP Body element. The value `:one` (the default) specifies that the SOAP Body consists of exactly one element. The value `:many` specifies that the SOAP body may contain any number of elements. This value must be specified if the SOAP message makes use of the multiRef feature.
- send-type: the value of this option controls the sending of a "xsi:type" attribute in outgoing SOAP messages. A value of `nil` suppresses the "xsi:type" attribute . A value of `t` causes an "xsi:type" attribute to be sent for any element with a named type definition. The value of the attribute is the name of the element type.

  The value of the option may also be a string or a symbol other than `t`; in this case, the value of the option is the value of the "xsi:type" attribute sent with any element that does not have an explicit :send-type option specified in the element or type definition.

- `:nillable value`: the value of this option specifies how element instances with an attribute "xsi:nil='true'" are handled. The possible values are:
  - `:ignore`: (the default, for compatibility with previous versions of the SOAP module) "xsi:nil" attributes are ignored. All elements will appear in the message returned to or passed to the application.
  - `:accept`, if an element appears with a "xsi:nil='true'" attribute and an empty content, then the element is not included in the message returned to or passed to the application.
  - `:strict`: the behavior is controlled by the element declaration. If the element is declared with a ":nillable t" option, then, if the element appears with a "xsi:nil='true'" attribute and an empty content, then the element is not included in the message returned to or passed to the application.
- message-init value: this option specifies the storage strategy used when collecting SOAP messages. Since the SOAP specification requires the message length to be included in the SOAP message header, the SOAP module must collect the entire message before sending it. Since this may require an indefinite amount of storage, we use an adjustable array.

  The default setting of 500 starts with an initial array of 500 characters, extended as needed using the ACL default vector-push-extend strategy (ie double the array size).

  If the message-init argument is specified as a positive integer, it specifies a different inital array size, and the default extension strategy.

  If the message-init argument is a list, the first element must be a positive integer that specifies the inital array size. The second element, if present specifies an array extension strategy. A positive integer causes the array to be extended by that amount over what is immediately needed. A real number less than 1.0 causes growth by the specified fraction over the current size. A real number greater than or equal to 1.0 causes growth by the specified ratio.

All other arguments are passed as initargs in a call to make-instance. Arguments recognized for the class `soap-aserve-server-string-in-out-connector` include:

- action: A default value for the string that must match the SOAPAction HTTP header in an incoming message. A value of `nil` means that there is no default action and action must be specified in each call to soap-export-method. A value of `:none` means that the SOAPAction header is ignored.
- lisp-package: The Lisp package for unqualified names in the incoming messages.
- message-dns: The default namespace map for namespaces specific to an application (see soap-message-client).
- base-dns: The default namespace map for the standard and required namespaces (see soap-message-client).
- must-understand: The default handling of MustUnderstand attributes in incoming messages (see soap-message-client).
- decode-flag: The default handling of undefined elements in incoming messages (see soap-message-client).
- encoding: The encodingStyle attribute sent with reply messages (see soap-message-client).
- actor: The actor attribute sent with reply messages (see soap-message-client).

The keyword arguments xml-leader, xml-encoding, http-method, http-protocol, content-type, http-agent, and :http-headers are described under soap-message-client.

If the SOAP server must use the HTTPS protocol with clients, then the start argument must include the `:ssl` and maybe the `:ssl-password` options (see aserve/aserve.html).

### enable-soap-server

### Generic Function

#### Package: net.xmp.soap

Arguments: server &key &allow-other-keys

This method enables the server to respond to SOAP method calls. The HTTP server is not affected by this call.

### disable-soap-server

### Generic Function

#### Package: net.xmp.soap

Arguments: server &key &allow-other-keys

This method disables the server for SOAP method calls. The HTTP server is not affected by this call.

### start-soap-server

### Function

#### Package: net.xmp.soap

Arguments: server &key new start enable &allow-other-keys

Start the HTTP server for this SOAP server. If new is non-`nil`, create a new HTTP server If start argument is specified, it overrides the start argument in call to soap-message-server If enable is non-`nil`, enable the soap server.

### stop-soap-server

### Function

#### Package: net.xmp.soap

Arguments: server &key disable &allow-other-keys

Stop the HTTP server for this SOAP server. If disable is non-`nil` disable the SOAP server as well.

## 8.2 Exporting Methods

A method must be exported to make it available to remote clients through the network server.

### soap-export-method

### Generic Function

#### Package: net.xmp.soap

Arguments: conn name signature &key lisp-name (enable t) return help action ordered exact &allow-other-keys

This function defines how a Lisp function will be invoked when a SOAP message arrives at the server. The arguments to the Lisp function are the names and content of the sub-elements in the message.

The arguments to soap-export-method are:

- conn: an instance of the class `soap-server-connector`, typically the result of a call to soap-message-server.
- name: a string or symbol that identifies the top (and only) element in the SOAP message body. If the name is a string, then the incoming message element can be in any namespace or in no namespace. If the name is a symbol in a package that has not been associated with a namespace, then it is equivalent to the string that is the symbol-name of the symbol. If the name is a symbol from a package associated with a namespace, then the message element MUST be qualified with the specified namespace.
- signature: a list of element names that must be or may be included in the message. The items in the list may be strings or symbols that are interpreted using the same rule as the name argument.
- lisp-name: the value can be a symbol naming the Lisp function that will be called when the message is accepted; or a list.

  If the value is a list, the first element in the list must be the name of the Lisp function that implements the method, and the remainder of the list must a list of keywords of the same length as the signature.

  When the Lisp function is called from the SOAP server, it will receive keyword arguments with keys from the above list. The value of each keyword argument will be the element contents corresponding to the matching element in the signature.

  For example, if we export

         (soap-export-method conn "myMethod" '("elt1" "elt2" "elt3")
                                  :lisp-name '(my-lisp-method :k1 :k2 :k3)
                                  :return "myMethodResponse")

  then the Lisp function must be defined as

      (defun my-lisp-method (&key k1 k2 k3) ...)

  When this function is called, keyword argument k1 will be present if the element with name "elt1" was present in the SOAP message, and so on. This may seem like the long way around the barn, but this notation allows the Lisp function to be isolated from the variations introduced by namespace-to-package mappings that may be outside the control of the Lisp implementation.

- enable: when non-`nil`, the method is enabled immediately. When `nil`, the method must be enabled before it may be called.
- return: element-name or element-def for the result message.
- help: the value should be a help string (or `nil`).
- action: This argument specifies the content of the HTTP SOAPAction header in the incoming message. If omitted, use the action specified in soap-message-server call.
  If `nil`, then ignore SOAPAction header in message.
  If `:none`, then ignore SOAPAction header in message.
  If `:default`, then use the action specified in soap-message-server call.
  If a string or symbol, then the SOAPAction header in message must match.
- ordered: if non-`nil`, elements in message must be in same order as in signature
- exact: if non-`nil`, every element in signature must be present in message

## 8.3 Controlling Access to Methods

The Lisp function associated with a SOAP message is called with the soap-invoke-method generic function. The SOAP API includes a method specialized on `soap-server-connector`. This method simply calls apply. Applications can add additional restrictions on how and when the function is called by implementing a more specific method on a sub-class of `soap-server-connector`.

### soap-invoke-method

### Generic Function

#### Package: net.xmp.soap

Arguments: server name arg-list &key headers

This function is called to invoke the Lisp function associated with a SOAP message. The default primary method simply calls apply. User methods can be defined for sub-classes of `soap-server-connector` to enforce more restrictive access rules.

The server argument is a fresh copy of a `soap-server-connector` instance. The name argument is the name of the Lisp function associated with the SOAP message. The arg-list argument is a list of arguments for the Lisp function; this is an alternating list of element names and element content values.

The headers argument is a list of LXML structures that represent the SOAP header elements that were included in the incoming message. The default method ignores these.

This function normally returns one value which is encoded as the content of the reply message. If zero values are returned, then a SOAP client fault with fault string "Call refused" is returned as the reply. Values other than the first are ignored.

An `:around` method specialized on `soap-server-connector` binds the variable `*soap-server*`. If more specific `:around` methods are defined, the body of these methods will not see this binding.

## 8.4 Defining SOAP Methods

The Lisp function defined as the SOAP method body is called with an &rest argument that consists of an alternating list of element names and element content values.

If the element names are Lisp keywords, the function may be defined with keyword arguments, otherwise the function must extract argument values by some other means such as getf.

When the incoming SOAP message body consists of multiple elements, only the first element is used to dispatch the method call. A list of body elements is obtained with the function soap-message-body.

If a method needs to return multiple body elements, the method return must be defined by a type-spec or a type-name that defines a sequence type. The value returned by the method must be a list of values suitable for encoding into that type.

Note that the returned value specified in soap-export-method may be an element name or a type name. If a type name is intended, then there must not be an element defined by the same name.

Named element content in message: | Lisp argument to method:
simple type | corresponding Lisp value
complex type | an association list in which the keys are sub-element names. The function soap-sub-element-content should be used to extract the content of a sub-element.
array type | a Lisp array of `t`, each array element is the element content of the array elements in the message

### *soap-server*

### Variable

#### Package: net.xmp.soap

During the execution of a SOAP method call, this variable is bound to a copy of the server instance that received the message with the method call.

### soap-message-body

### Generic Function

#### Package: net.xmp.soap

Arguments: conn

When conn is an instance of `soap-connector`, this accessor method returns a list of all the body elements in the SOAP message.

The following accessor methods return the corresponding components of the incoming SOAP message. They take an instance of `soap-server-connector` as their argument.

### soap-server-message-method

### Generic Function

#### Package: net.xmp.soap

Arguments: conn

Accesses the method component of the incoming SOAP message associated with conn, which must be a `soap-server-connector`.

### soap-server-message-return

### Generic Function

#### Package: net.xmp.soap

Arguments: conn

Accesses the return component of the incoming SOAP message associated with conn, which must be a `soap-server-connector`.

### soap-server-message-signature

### Generic Function

#### Package: net.xmp.soap

Arguments: conn

Accesses the signature component of the incoming SOAP message associated with conn, which must be a `soap-server-connector`.

### soap-server-message-action

### Generic Function

#### Package: net.xmp.soap

Arguments: conn

Accesses the action component of the incoming SOAP message associated with conn, which must be a `soap-server-connector`.

### Some convenience functions for writing method bodies:

### soap-sub-element-content

### Function

#### Package: net.xmp.soap

Arguments: element-item pattern &rest more-patterns

Use of this function is deprecated. Use soap-result-part instead.

This function is used to extract the sub-element content from an argument to a SOAP method. The sub-element-name must be the name of an immediate sub-element of the argument.

If the sub-element is a simple element, the value is a Lisp atom that represents the value of the element. If the sub-element is a complex element, the value is a Lisp association list that can be decomposed with additional calls to soap-sub-element-content.

### soap-alist-to-plist

### Function

#### Package: net.xmp.soap

Arguments: element-alist &optional recursive

Translate an association list into a property list. This is useful when turning an argument into a reply.

### soap-encode-object

### Generic Function

#### Package: net.xmp.soap

Arguments: conn name type-spec data

This function returns an instance of soap-element that contains an encoded form of the data argument using the type-spec to control the encoding. If the name argument is the name of an element previously defined with define-soap-element, then type-spec may be `nil`; in that case the definition of the element is used.

Once a value is encoded as a soap-element instance, it is not affected by other element or type specifications that may be applied to the value. This function may be used to specify the encoding of SOAP array elements when a uniform encoding rule cannot be specified.

The conn argument may be `nil` or a soap-connector instance. If `nil`, we use the value of `*soap-server*`; thus the first argument may be `nil` in the body of a SOAP server method.

### soap-version

### Function

#### Package: net.xmp.soap

Arguments: &optional v1 v2 v3 error-p

In its simplest form, with no arguments, this function returns a string containing the current version information.

If the first argument is `t` or a stream, the version string is written to the stream (`t` indicating `*terminal-io*`).

If the first argument is an integer, the function acts as a predicate that compares the integer arguments to the current version. If v2 or v3 are omitted, they default to zero.

- If the version specified by v1, v2, and v3 is less than or equal to the current version, then the function returns a list containing the current version numbers.
- If the version specified by v1, v2, and v3 is higher than the current version, then, if the error-p argument is `nil` the function returns `nil`; otherwise, the function signals an error.

### soap-result-part

### Generic Function

#### Package: net.xmp.soap

Arguments: conn result name &rest more-names

When the conn argument is a `soap-connector` instance, the primary method extracts the named components from the result returned by call-soap-method.

The result argument should be the value returned by call-soap-method, an intermediate result returned by soap-result-pair, the list returned by soap-message-body, or a top-level element in the list returned by soap-message-body.

(See the note in the description of soap-result-pair about the eq'ness of suitable arguments to soap-result-pair and the return value of soap-result-pair.)

name may be `nil` to specify that the top-level element name in result is ignored. If not `nil`, name must be a string or symbol that is matched to the top-level element name in result or an integer that simply selects the sub-element by index.

more-names may be a list of `nil`, string, symbol or integer. Each item in the list is matched to the next level of nested sub-structure in result.

If the specified sub-element is found, the value returned is the sub-element content. Otherwise, the returned value is `nil`.

If multiRef references need to be followed, conn must be the `soap-connector` instance which received the result being examined. The table of reference definitions is saved in the `soap-connector` instance when the SOAP message is decoded.

### soap-result-string

### Generic Function

#### Package: net.xmp.soap

Arguments: conn result name &rest more-names

Like soap-result-part, but returns a single string if result is a list of strings.

### soap-result-only

### Generic Function

#### Package: net.xmp.soap

Arguments: conn result error-p name &rest more-names

Like soap-result-part, but behavior is controlled by error-p argument if the component is not found. The values of error-p can be:

- `:error` - signal an error
- other lisp value - return this value

### soap-result-typed

### Generic Function

#### Package: net.xmp.soap

Arguments: conn result type-spec error-p name &rest more-names

Like soap-result-only, but additional type conversions or tests may be done based on type-spec argument.

Current implementation looks for `xsd:string` only.

### soap-result-pair

### Generic Function

#### Package: net.xmp.soap

Arguments: conn result name &rest more-names

Like soap-result-part, but returns the cons that begins with the last named sub-element. This result is a suitable argument to soap-get-attributes and soap-get-attribute, or subsequent calls to soap-result-*.

Note that if x is a suitable argument to soap-result-pair, then `(eq x (soap-result-pair conn x nil))` is always true. Thus to descend into the sub-elements of a result, the sub-element is passed as the second name in the argument list. The first name in the list must be `nil` or the name of the element represented by the result argument.

### soap-get-attributes

### Generic Function

#### Package: net.xmp.soap

Arguments: conn pair

pair is a SOAP message element as returned by call-soap-method or as extracted with soap-message-body or soap-result-pair.

Value is `nil` or property list of `(name value ...)` where both name and value are strings.

### soap-get-attribute

### Generic Function

#### Package: net.xmp.soap

Arguments: conn pair name &optional default

pair is a SOAP message element as returned by call-soap-method or as extracted with soap-message-body or soap-result-pair.

name may be a string to match any attribute namespace or a symbol for exact match.

Value is `nil` or value of attribute. If the attribute is not found, return the default value.

## 9.0 Programming Notes

## 9.1 Multiple Threads

A client connector instance should be used serially only. Only one thread should access the connector for the entire duration of a message round-trip.

When a server responds to an incoming message, a copy of the server connector instance is cloned for the duration of the message. The variable `*soap-server*` is bound in the thread that calls the Lisp function exported to handle the message. Message handling programs called by the server must take care to deal with shared resources with appropriate interlocks.

## 9.2 Connector Class Hierarchy

The complete class hierarchy for sub-classes of `soap-connector` includes all the following classes:

       soap-connector

       soap-client-connector
       soap-server-connector

       soap-string-out-connector
       soap-string-in-connector
       soap-string-in-out-connector

       soap-client-string-out-connector
       soap-client-string-in-connector
       soap-client-string-in-out-connector

       soap-server-string-out-connector
       soap-server-string-in-connector
       soap-server-string-in-out-connector

       soap-aserve-connector

       soap-aserve-client-connector
       soap-aserve-server-connector

       soap-aserve-string-out-connector
       soap-aserve-string-in-connector
       soap-aserve-string-in-out-connector

       soap-aserve-client-string-out-connector
       soap-aserve-client-string-in-connector
       soap-aserve-client-string-in-out-connector

       soap-aserve-server-string-out-connector
       soap-aserve-server-string-in-connector
       soap-aserve-server-string-in-out-connector

Methods in the API and internals methods are specialized on the least-specific method in this hierarchy, but only the classes

      soap-aserve-client-string-in-out-connector
      soap-aserve-server-string-in-out-connector

are actually instantiated in an application using this API. Thus, in order to provide behavior specific to a given application the programmer must create a sub-class of one or both of the above classes.

The following are accessors for `soap-connector`. Values are used by encode-wsdl-file.

### soap-port-name

### Generic Function

#### Package: net.xmp.soap

Arguments: soap-connector

Returns the port name.

### soap-binding-name

### Generic Function

#### Package: net.xmp.soap

Arguments: soap-connector

Returns the binding name.

### soap-service-name

### Generic Function

#### Package: net.xmp.soap

Arguments: soap-connector

Returns the service name.

## 9.3 When things go wrong - debugging SOAP interfaces

Sometimes, when a connection does not seem to be working, it is useful to see the actual XML message strings passed between client and server.

The variable `*soap-client-debug*` can be set to a non-`nil` value to cause a printout of the HTTP headers and the XML message text sent by the client. When the reply arrives, the HTTP headers and XML message text are printed as well.

If the variable is set to `:stop`, then the message is not sent to the server.

The variable `*soap-server-debug*` can be set to a non-`nil` value to cause a printout of the HTTP headers and the XML message text received by the server and sent as a reply.

The debug flag can also be associated with a single client or server connection by using the soap-debug keyword initarg in the call to soap-message-client or soap-message-server.

If the variables `*soap-client-debug*` or `*soap-server-debug*` are stack bound, the stack bound value takes precedence over the slot or the global value.

The formal definitions of these two variables are given below.

When creating a new SOAP server, it may be helpful to exercise the server code with sample data without writing a client program. There are two (internal) functions that may help:

- net.xmp:xmp-run-one-file (Arguments: server-instance message-file): the message-file argument points to a file that contains the XML for a SOAP message to the server. The function runs the server for that one message.
- net.xmp:xmp-server-implementation (Arguments: server-instance message): the message argument may be a string containing the XML representation of the message, or a stream that will supply the XML representation of the message. The function runs the server for that one message.

### *soap-server-debug*

### Variable

#### Package: net.xmp.soap

When non-`nil`, causes the printing out of the HTTP headers and the XML message text received by the server and sent as a reply.

### *soap-client-debug*

### Variable

#### Package: net.xmp.soap

When non-`nil`, causes the printing out of the HTTP headers and the XML message text sent by the client. When the reply arrives, the HTTP headers and XML message text are printed as well.

## 9.4 I18N Issues

Character encoding is specified with the `:xml-encoding` option to soap-message-client and soap-message-server.

The Content-Type is specified with the `:content-type` option to soap-message-client and soap-message-server. The character encoding specified in the XML header must be consistent with the Content-Type specified in the HTTP header. Because of the wide range of possible encoding and conent types, it is impossible to give specific recoomendations for the settings of these parameters.

If additional HTTP headers are needed, they can be specified in the `:http-headers` option to soap-message-client and soap-message-server.

## 10.0 WSDL Support

Many web services are defined in an XML dialect known as WSDL. The WSDL definition specifies the element content and data types in the SOAP messages received and sent by the service.

Given a web service WSDL definition, we can generate the Lisp functions and definitions needed to send messages to the service and to receive and decode the replies.

We can also generate the server interface and skeleton definitions for the server methods. The only additional programming needed is to supply the body of the server functions.

## 10.1 Limitations in WSDL support

This early release of WSDL support implements most of the WSDL 1.1 specification. Any omissions are the result of oversight or for the benefit of an earlier release.

The known omissions include:

- This implementation cannot decode most declarations specified with a `<restriction>` construct. These types are translated to `(:complex (:seq* (:any)))`. This translation will accept most input data, but output messages will most likely be encoded incorrectly. The affected declarations must be modified manually.
- This implementation ignores `soap:header` and `soap:fault` entries in a file.
- This implementation ignores `minOccurs` and `maxOccurs` attributes
  - for `xs:sequence` we assume `min=0 max=Unbounded`
  - for `xs:all` we assume `min=0 max=1`
  - for `xs:choice` we assume `min=0 max=1`

## 10.2 WSDL Functions and Variables

The packages `net.xmp.wsdl` and `net.xmp.wsdl.soap` hold the symbols in the WSDL namespaces.

### wsdl-file-connector

### Class

#### Package: net.xmp.soap

An instance of this class is created when a WSDL file is decoded.

### wsdl-file-connector

### Function

#### Package: net.xmp.soap

[Earlier releases of this document incorrently described a function of this name. There is no such function.]

### decode-wsdl-file

### Function

#### Package: net.xmp.soap

Arguments: file &key namespaces base lisp-package class init xml-syntax include import verbose

This function parses a file containing a WSDL specification and returns a `wsdl-file-connector` instance containing the parsed data.

The lisp-package argument is a package specifier. Unqualified WSDL names will be interned in this package.

The namespaces keyword argument may be `nil`, `:decode`, or a namespace map. The default is `:decode`.

The base keyword argument may be `nil` or a namespace map. The default is `:wsdl1-prefix`.

If a package-name occurs as an ex-ns-part, any unknown namespaces in the file are mapped to this package. Only one package-name should occur in the `extended-namespace-spec`.

If the form `(:prefix symbol-or-string)` occurs as an ex-ns-part, each unknown namespace is mapped to a different package named "prefixNN". Only one such form should occur in the `extended-namespace-spec`.

The `ex-ns-tail` component specifies how the standard namespaces should be identified in the file. If the package-name or `:prefix` forms occur as an `ex-ns-part`, or if the tail is `:guess`, then decode-wsdl-namespaces is called.

When the namespaces keyword argument is `:decode`, decode-wsdl-namespaces is called with the map argument set to base and if the namespaces can be decoded, the resulting namespace map is used. Otherwise an error is signaled.

The value of the class argument should be the name of a sub-class of `wsdl-file-connector`. The default is `wsdl-file-connector`.

The value of the init argument should be a list of initargs added to the call of make-instance of the class.

The value of the xml-syntax keyword argument can be `:strict` or `nil` (or any other value). A value of `:strict` forces strict interpretation of Schema definitions. Any other value relaxes XML Schema syntax to allow many ill-formed constructs that we have encountered in published Schema definitions. The default is `nil`.

The include keyword argument specifies how XML schema <include> elements should be handled in the WSDL Schema. A value of `nil` (the default) causes <include> elements to be ignored; this behavior may leave many types and elements undefined. A non-`nil` atomic value is assumed to be a function of two arguments: the `wsdl-file-connector` instance, and the value of the "schemaLocation" attribute in the <include> element. If the non-`nil` value is of the form `(op . rest)`, op is assumed to be a function of 2+n arguments where the first two arguments are as above, and the remaining arguments are the items in rest. In both cases, the value returned by the function must be `nil` or a string. A `nil` indicates that the <include> element should be ignored. A string is assumed to be the XML content to be parsed as the included Schema.

The import keyword argument specifies how XML schema <import> elements should be handled in the WSDL Schema. The values and handling are like include.

If the value of the verbose keyword argument is non-`nil`, progress messages are printed. The default is `nil`.

### decode-wsdl-string

### Function

#### Package: net.xmp.soap

Arguments: string &key namespaces base lisp-package class init xml-syntax

This function is like decode-wsdl-file but the input is from the string argument instead of a file.

### decode-wsdl-at-uri

### Function

#### Package: net.xmp.soap

Arguments: uri &key namespaces base lisp-package class init xml-syntax

This function is like decode-wsdl-file but the input is from the specified uri argument instead of a file.

### decode-wsdl-source

### Function

#### Package: net.xmp.soap

Arguments: &key uri string file namespaces base lisp-package class init xml-syntax stream

This is the most general form of decode-wsdl-* functions. Only one of the keyword arguments uri, string, file, and stream should be specified. The specified argument determines the input source.

Those arguments are interpreted in this order:

1. If uri is non-`nil`, the data at the URI is retrieved and treated as the WDSL source string.
2. If string is non-`nil`, it is treated as the WDSL source string.
3. If file is non-`nil`, the content of the file is treated as the WDSL source string.
4. If stream is non-`nil`, it is assumed to be positioned at the first character of the WDSL source string.

If all the source arguments are `nil`, an error is signaled.

The other keyword arguments are like decode-wsdl-file with the following exception: the value of the namespaces argument cannot be `:decode` when the source is a stream. This is because when namespaces is `:decode`, the source is parsed twice, once to find all the namespace declarations, and again to decode the content. If the source is a stream, we do not attempt to reposition the stream; therefore only one pass is allowed.

### soap-make-fault

### Function

#### Package: net.xmp.soap

Arguments: server code string &key factor detail sub-code

This function creates an encoded fault instance.

The server argument must be an instance of a SOAP connector.

The code argument may be a keyword to specify one of the pre-defined SOAP Fault codes in the table below, or it must be a symbol in a namespace package.

       :server           "SOAP-ENV:Server"
       :client           "SOAP-ENV:Client"
       :version-mismatch "SOAP-ENV:VersionMismatch"
       :must-understand  "SOAP-ENV:MustUnderstand"

The sub-code if specified it is appended to the fault code and separated with a dot.

The string argument is encoded as the "faultstring" element content.

The factor argument is encoded as the "faultfactor" element content.

The detail argument is encoded as the "detail" element content.

If a SOAP method implementation throws an encoded fault instance, then the SOAP reply message consists of the contained fault message. If a SOAP method implementation throws any other value, it is encoded as a "Client.LispError" fault.

### soap-new-environment

### Function

#### Package: net.xmp.soap

Arguments:

This function resets the SOAP environment by removing all namespace, namespace map, element and type definitions from the Lisp environment and restores the initial definitions included in the SOAP module.

### encode-wsdl-file

### Function

#### Package: net.xmp.soap

Arguments: file &key namespaces base servers target target-package name (if-exists :supersede) types elements

Create a file with WSDL definitions of the specified servers. The definitions include exported methods and associated data types.

The arguments are:

- file: string or pathname naming output file
- namespaces: the value of this argument is a namespace map that is combined with the base namespace map to define the default namespace map for the WSDL definition. The default value is the list `(:net.xmp.wsdl)` that specifies the WSDL namespace as the default namespace.

  The effective namespace map during the encoding af each service is obtained by combining the namespace map of the service with the above default namespace map for the WSDL definition.

- base: the value of this argument is a namespace map. The default value is the list `(list nil :wsdl1-namespaces :all)`.
- servers: a list of soap-message-server instances, a single instance, or a list of 2-lists (service-name soap-message-server-instance).
- target: a URI string or a symbol naming a package. This argument specifies the target namespace for the entire WSDL definition. The current implementation of the WSDL generator assumes that all the top-level message elements are in the same namespace.

  If this argument is omitted, we use the URI "urn:ThisWebServiceNamespace" as the target, and expect all the top-level message elements to be in no pre-defined namespace.

  If this argument is a symbol, it must name a package associated with a namespace in the namespaces argument. If the argument is a string or a URI instance, and it is not mentioned in the namespaces argument, then all top-level message elements are assumed to be in this namespace.

  If a top-level message element is encountered in another namespace, an error is signalled (unlesss the target-package argument is specified).

- target-package: can be `nil`, the name of a package, or a package. When this argument is non-`nil`, it serves as a filter for messages to be included in the WSDL output. Only messages in the specified package are included in the WSDL output.
- name: the name of the service
- if-exists: default is `:supersede`
- types: a list of type names. The type definitions are added to the types Schema of the WSDL output.
- elements: a list of element names. The element definitions are added to the types Schema of the WSDL output.

The types and elements arguments may be used to add element and type declarations that are not mentioned in any SOAP messages, or with a null services argument to generate a WSDL output without any service definitions.

### wsdl-service-names

### Generic Function

#### Package: net.xmp.soap

Arguments: conn &optional and-ports

Returns a list of the names of all the services defined in the wsdl file. The order of the names is the order of the definitions in the file. If more than one service is defined, the index in the list may be used as the service argument to make-client-interface.

The optional and-ports argument determines the level of detail included in the returned value. If it is omitted or `nil`, the result will look like `(service-name ... )`. If it is t, the result will look like `((service-name port-name ...) ... )`. If it is :verbose, the result will look like `((service-name (port-name binding url) ...) ... )`.

### make-client-interface

### Generic Function

#### Package: net.xmp.soap

Arguments: conn service destination &key eval (lisp-package :keyword) (file-package :user) empty-element null-element expand-singleton prefix suffix port if-missing-package map compose text-file class-file post-file object-class action message-dns body-form message-method-prefix connect-class built-in-arrays defined-arrays sequence response redef object-access generate-comments

This function generates a source code file with type definitions, element definitions and function definitions derived from the WSDL definition in the conn argument. The client interface is intended to be a fully functional set of functions to access the web service described in the WSDL.

Some web service definitions may change over time, and therefore the interface code may need to be generated repeatedly. The many arguments to make-client-interface attempt to capture all the variations that may be needed to generate usable code so that the generated code will require little if any hand modifications.

The conn argument must be a `wsdl-file-connector` instance as returned by decode-wsdl-file.

The service argument can be

- `nil` or omitted, in which case 0 is passed (see next entry).
- an integer: which is interpreted as an index into a list of defined services
the keyword `:none`, in which case service definitions are ignored, but any types defined in the <wsdl:types> element are translated to Lisp/SOAP type definitions.
- a string-or-symbol: which is interpreted as the name of defined service

The destination argument can be

- a stream, which causes output to be sent to that stream
- `nil`, which supresses output
- `t`, which causes output to be sent to the `*standard-output*` stream
- a string or a pathname, which should specify an output file to receive output

### The keyword arguments

- eval: the eval argument is ignored.
- lisp-package: this argument specifies the `:lisp-package` argument of the generated call to soap-message-client. The default is `:keyword`.
- empty-element this argument specifies the `:empty-element` argument of the generated call to soap-message-client.
- null-element: this argument specifies the `:null-element` argument of the generated call to soap-message-client. Thus, this argument value may be the name of a special variable or a function call; if that is the case, the behavior of the generated code may be modified at run time by changing the value of the special variable or by changing the definition of the called function.
- file-package: this argument denotes the package for the source file that is generated by this function. The default is `:user`.
- expand-singleton: when this argument is `nil`, each generated client function expects as many keyword arguments as there are immediate components in the SOAP message.

  When the expand-singleton argument is non-`nil`, and the SOAP message consists of exactly one sub-element, the generated client function expects as many keyword arguments as there are immediate components in this singleton sub-element. SOAP messages are often designed to contain this structure, and this feature simplifies the client message function arguments.

- prefix: this argument is the leading component of the generated names of client functions. The argument must be a string or a symbol. The default is `:client-`.
- suffix: this argument should be one of the keywords `:index`, `:message`, or :compose. The keyword `:index` denotes names like prefix-17. The keyword `:message` denotes names like prefix-SoapMessageName. The keyword `:compose` causes the name translation specified in the compose argument to be applied to the message name suffix. The default is `:index`.
- port: this argument specifies the port binding within a service. The value is a name string or an index. The default is 0.
- map: this argument should be a keyword symbol used as the name of the namespace map generated for the interface. The default is `:<prefix>namespaces` where `<prefix>` is the value of the prefix argument.
- compose: this argument specifes how names from the WSDL definition are translated into Lisp symbols. By default, this translation applies only to symbols generated by the object-class option. If the suffix argument is specified as `:compose`, then this option also applies to message calling function names. This argument can be any of the following values:

  `:hyphen`, `:hyphen-if-ok` (the default), `:downcase`, `:downcase-if-ok`, `:capitalize-accessor`, or `:capitalize-all`

  If the value is `:hyphen-if-ok` or `:downcase-if-ok`, add a hyphen at the case change location and downcase or simply downcase but no hyphen (respectively) if no apparent case-fold conflicts results. The value `:hyphen` causes a hyphen to be added and downcasing unconditionally. The value `:downcase` causes downcasing (but no hyphen) unconditionally.

  `:capitalize-accessor` capitalizes accessor roots while `:capitalize-all` capitalizes all roots. Here are some examples:

      :compose=:capitalize-accessor reader-prefix slot="get":
      The slot "unitPrice" reader will be "getUnitPrice"
      The decoder for type "itemList" will be "decode-itemList"

      :compose=:capitalize-all:
      The slot "unitPrice" reader will be "GetUnitPrice"
      The decoder for type "itemList" will be "Decode-ItemList"

  #### Value of :compose may be a list

  The argument may also be a list beginning with one of the above keywords. The remainder of the list is a list of exceptions in the following format:

      (compose-keyword exception ... )
      exception -> string -- a matching input string is kept unchanged
                -> (string-in string-out) -- an input string matching
                                            string-in isr eplaced with string-out

      Examples:

        :compose '(:hyphen "oddCap" ("BADcap" "bad-cap"))
      Default translation: "odd-cap" "ba-dcap"
      With above exceptions: "oddCap" "bad-cap"

- text-file
- class-file
- post-file: these three arguments specify where various generated source lines will be written. The value of each may be a stream, a pathname, `:insert` (the default for class-file and post-file), or `nil`. The value of text-file may also be `:txt`, which is also the default for text-file.

  The value `nil` suppresses the output. The value `:insert` inserts the output in the main destination output file. A stream or pathname value specifies the file where the output is written.

  The text-file argument specifies where a text comment describing the interface will be written. The value `:txt` (the default) specifies a file with the same name as the main destination output file and a file type of "txt".

  The class-file argument specifies where defclass forms and wrapper functions will be written.

  The post-file argument specifies where forms generated by a user wsdl-post-process method will be written.

- object-class: this argument can be `nil`, a class name, a class, or an instance. The specified class must be a sub-class of `soap-object-class`. When this option is specified as non-`nil`, generate code to map between SOAP structs and instances. See Section 10.4 Mapping SOAP Structures to CLOS classes for more details.
- if-missing-package: this argument specifies the behavior if a namespace cannot be mapped to a package. The value can be `:error` or `:warn` or a string or a symbol.

  If the value of if-missing-package is `:error` or `:warn` (the default), an error or a warning is signaled. When the `:warn` option is chosen, if no warnings are printed, the generated interface is complete and correct. If warnings are printed, the generated interface file must be hand modified to make it complete and functional. It is usually easier to adjust the namespaces argument and generate a new interface file.

  If the value of if-missing-package is a string or some other symbol, then a package with name "net.xmpns.SSSNN" where SSS is the string (or symbol-name) and NN is an index is created and used.

  If no Lisp package has been defined for a namespace, the warning "There is no Lisp package defined for namespace ~S" is printed. If a Lisp package is not pre-defined in the application, the symbols will be interned in a new package for each new incoming message.

- action: this argument specifies a default `soapAction` header for a generated server.
- message-dns: this argument specifies a default message-dns option for a generated server.
- body-form: this argument specifies the body-form option for the generated client or server.
- message-method-prefix: when this argument is non-`nil`, a set of wrapper generic functions are generated (see Section 10.4.4 Call Wrapper Methods).
- connect-class: this argument specifies the connector class used in the generated client or server code. The defaults are `soap-aserve-client-string-in-out-connector` and `soap-aserve-server-string-in-out-connector`.
- built-in-arrays: this argument specifies the behavior for Schema types defined as arrays of built-in types. If the value is `:collapse`, then the generated code replaces the named array type with an explicit array declaration. Thus:

      (define-soap-type nil foo '(:array xsd:string))

      ;; built-in-arrays=nil
      (define-soap-element nil 'bar 'foo)

      ;; built-in-arrays=:collapse
      define-soap-element nil 'bar '(:array xsd:string))

- defined-arrays: this argument specifies the behavior for Schema types defined as arrays of user-defined types. If the value is `:collapse`, then the generated code replaces the named array type with an explicit array declaration.
- sequence: this argument can specify a less restricted interpretation of the Schema <sequence> collection definer. The formal Schema definition states that a <sequence> is ordered, but some web services seem to ignore this restriction and treat <sequence> as unordered. When the value of this argument is `:set*`, then elements that were defined as `:seq*` composites in the WSDL are actually defined as `:set*` in the generated code.
- response: the value of this argument may be the keywords `:string` or `:symbol`. The default is `:string`. Normally SOAP response elements are defined without namespace qualifiers since both the name and namespace of the top-level response element is ignored. When the value `:symbol` is specified, then the response element is defined in the same package and namespace as the SOAP request method name. This feature may avoid some name conflicts if several WSDL definitions are combined in one Lisp image.
- redef: the value of this argument controls how class definitions are generated when the object-class argument is specified. The default value is `nil`, no action.

  A value of `:warn` causes a warning if a class definition is generated but a class definition already exists from a source file different from the destination file.

  A value of `:skip` causes a generated class definition to be omitted if a class definiton already exists from a source file different from the destination file.

  A value of `:skip-and-warn` causes a generated class definition to be omitted if a class definiton already exists from a source file different from the destination file but a warning is signalled as well.

  This option is useful if multiple WSDL definitions with duplicate elements are combined in one Lisp image. The option is effective only if each WSDL interface is generated and loaded before the next WSDL is analyzed.

- object-access: the value of this argument controls the package where object class accessors are generated. If the value is `nil` (the default), accessors are generated in the output file package. If the value is `:object-class`, then accessors are generated in the package of the object class; this is the package associated with the namespace of the SOAP Schema type.

  When this argument value is `:object-class`, then encoder names are generated without a prefix.

- generate-comments: when this argument is non-`nil`, the generated code file contains comments that show where wsdl-generate-code is called during code generation. The comments show the arguments to wsdl-generate-code in each situation. This output may help in designing application specific methods for wsdl-generate-code.

In order to define the generated interface, the generated interface file must be compiled and loaded.

To review, these arguments control the generated code:

- prefix: string or symbol
- suffix: `:index` or `:message`
- map: a namespace-map
- action: a string (server only)
- message-dns: a namespace-map (server only)
- file-package: a package or package-name
- expand-singleton: a boolean
- body-form: `:one` or `:many`
- object-class: `nil` or name of class (subclass of `soap-object`)
- compose: `:hyphen`, `:hyphen-if-ok`, `:downcase`, `:downcase-if-ok`, or `nil`
- message-method-prefix: a string or symbol
- connect-class: `nil` or name of class (subclass of `soap-connector`)
- built-in-arrays: `nil` or `:collapse`
- defined-arrays: `nil` or `:collapse`
- send-atype: a boolean
- send-asize: a boolean
- null-element: `nil` or `:default-value` or `:empty`
- empty-element: `nil` or `:default-value`
- lisp-package: a package or package-name
- sequence: `nil` or `:set*`

### Possible name conflicts

When generating Lisp code from a WSDL definition, there may be name conflicts or possible name conflicts when several different spellings are mapped to the same Lisp symbol. These conflicts are signaled as warnings of the form:

    Possible name conflicts: (key (symbol from...)...)

where each from component is a string or a list of strings used to derive the name of the symbol.

### make-server-interface

### Generic Function

#### Package: net.xmp.soap

Arguments: conn service destination &key eval (lisp-package :keyword) (file-package :user) empty-element null-element expand-singleton prefix suffix action message-dns port if-missing-package map response redef object-access generate-comments

This method analyzes the data in the WSDL file to generate type definitions and server function skeletons.

Most of the arguments are as for make-client-interface. The eval argument, as in make-client-interface, is ignored.

The prefix argument is the leading component of the generated names of server functions. The argument must be a string or a symbol. The default is `:server-`.

The action argument is the default `soapAction` expected for all incoming messages.

The message-dns argument is used to initialize the namespace definitions of the server instance.

In order to define the generated interface, the generated interface file must be compiled and loaded.

### wsdl-include-file

### Function

#### Package: net.xmp.soap

Arguments: conn file-name

This function may be used as the value of the import or include keyword arguments to decode-wsdl-file. The returned value is `nil` or the contents of the specified file.

### wsdl-include-url

### Function

#### Package: net.xmp.soap

Arguments: conn url-string

This function may be used as the value of the import or include keyword arguments to decode-wsdl-file. The returned value is `nil` or the contents of the specified url.

## 10.3 Namespaces and Packages

The meaning of XML, SOAP, and WSDL texts depends in part on the correct identification of various namespaces.

XML namespaces are identified by a URI and URIs are considered distinct if they differ in any character position. The SOAP module considers two URIs equivalent if they only differ in a final slash character.

## 10.3.1 Some important namespaces and packages

### XML Schema definition namespace

- The qualifying prefix is usually "xs" or "xsd".
- The Lisp package is :net.xmp.schema.
- The URI varies - we have seen

           "http://www.w3.org/2001/XMLSchema"
           "http://www.w3.org/2000/10/XMLSchema"
           "http://www.w3.org/1999/XMLSchema"

### XML Schema instance namespace

- The qualifying prefix is usually "xsi".
- The Lisp package is :net.xmp.schema-instance.
- The URI varies - we have seen "http://www.w3.org/2001/XMLSchema-instance" and "http://www.w3.org/2000/10/XMLSchema-instance"

### SOAP message envelope namespace:

- The qualifying prefix in the SOAP spec is "SOAP-ENV".
- The Lisp package is :net.xmp.soap.envelope
- The only URI we have seen is "http://schemas.xmlsoap.org/soap/envelope/"

### SOAP message encoding namespace

- The qualifying prefix in the SOAP spec is "SOAP-ENC".
- The Lisp package is `:net.xmp.soap.encoding`.
- The only URI we have seen is "http://schemas.xmlsoap.org/soap/encoding/"

### WSDL definition namespace

- The qualifying prefix varies.
- The Lisp package is `:net.xmp.wsdl`.
- The URI in the WSDL 1.1 spec is "http://schemas.xmlsoap.org/wsdl/"
- The URI in the WSDL 1.2 spec is "http://www.w3.org/2003/06/wsdl"

### WSDL SOAP binding namespace

- The qualifying prefix varies.
- The Lisp package is `:net.xmp.wsdl.soap`.
- The URI in the WSDL 1.1 spec is "http://schemas.xmlsoap.org/wsdl/soap/"
- The URI in the WSDL 1.2 spec is "http://www.w3.org/2003/06/wsdl/soap12"

## 10.3.2 Namespace Definition Operators

A namespace declaration is a list of the form `(package prefix uri)`.

One package may be linked to several URIs. One URI may be linked to several packages. The most recent definition is the first to be seen in a search. The primary-p argument to various operators allows some reordering.

One advantage of making a global namespace definition is that the package name may be used to denote the mapping. Also the entry will be found if :all is in namespace map.

Here is a recursive specification of the namespace maps:

    namespace-map -> symbol-name-of-namespace-map |
                     (default-namespace [namespace-entry]... [namespace-tail])
    default-namespace -> nil        ;; no default specified,
                                          ;; inherit the current default or continue
                                          ;;    the search for a default specification
                       -> ""         ;; the default is to have no default at all
                                           ;;   blocks any inherited default
                                           ;;   and stops the search for a default
                       -> symbol     ;; package name of defined namespace
                       -> string     ;; search in order
                                           ;;   1. package name of defined namespace
                                           ;;   2. uri
                       -> uri instance ;; uri
    namespace-entry -> (package-name) | (package-name prefix) |
    		     namespace-declaration | namespace-declaration-instance
    		     symbol-name-of-namespace-map |
    		     :all
    		     :stop
    namespace-tail -> nil | (package nil :any) | (string nil :prefix)

### xmp-namespace-map

### Class

#### Package: net.xmp.soap

The Lisp class of a namespace map object.

### define-namespace-map

### Function

#### Package: net.xmp.soap

Arguments: name &rest namespace-map-parts

This function returns a `xmp-namespace-map` instance.

The name argument may be `nil`, to define an anonymous namespace map. The namespace-map-parts argument may be `nil` to define an empty namespace map. If the list is not `nil`, it must begin with a default namespace specification. The general format of the list is

      default-namespace [namespace-entry]... [namespace-tail]

Where the `default-namespace` component may be

- `nil` to denote no default.
- a package defined to represent a namespace.
- a symbol that names a package defined to represent a namespace.
- a string that names a package defined to represent a namespace. If the string does not name a package, then it is treated as a URI.
- a URI instance that identifies a namespace.

The `namespace-entry` and `namespace-tail` components are described in Section 10.3.2 Namespace Definition Operators.

### Defined namespace-map keywords (read-only):

     :wsdl-namespaces ->  ( :wsdl1.2 :wsdl1.1 :soap )
    	 This definition recognizes both the WSDL 1.1
    	 and the  WSDL 1.2 namespaces, and uses the WSDL 1.2
    	 namespaces for output, since they appear first.

     :wsdl1-namespaces -> ( :wsdl1.1 :wsdl1.2 :soap1 )
    	 This definition uses the WSDL 1.1
    	 namespaces for output, since it appears first.

     :soap -> ( :soap1.2 :soap1.1 :schema )
     :soap1 -> ( :soap1.1 :soap1.2 :schema )

     :soap1.1
     :soap1.2
     :wsdl1.1
     :wsdl1.2

     :schema -> ( :schema2001 :schema1999 )
     :schema1 -> ( :schema1999 :schema2001 )

     :schema1999 :schema2001

     :wsdl-combine ->  ( :wsdl-namespaces :all (:wsdl-data nil :any) )
    	 This definition searches the :wsdl-namespaces first,
    	 then any globally declared namespaces.
    	 This definition maps any unmatched namespaces to the
    	 :wsdl-data package.

     :wsdl-keyword ->  ( :wsdl-namespaces :all (:keyword nil :any) )
    	 This definition maps any unmatched namespaces to the
    	 keyword package.

     :wsdl-prefix  ->  ( :wsdl-namespaces :all ("wsdl-" nil :prefix) )
    	 This definition maps each unmatched namespace to a new
    	 package with a name of the form "wsdl-nnn"

     :wsdl1-combine -> ( :wsdl1-namespaces :all (:wsdl-data nil :any) )
     :wsdl1-keyword -> ( :wsdl1-namespaces :all (:keyword nil :any) )
     :wsdl1-prefix  -> ( :wsdl1-namespaces :all ("wsdl-" nil :prefix) )

The current namespace environment is defined as the current nesting of namespace declarations. It consists of nested :namespaces options and/or xmlns attributes, the :message-dns slot specification, the :base-dns slot specification, and finally the namespace-tail entry.

During input decoding, when the server is decoding a request or a client is decoding a reply, or when decoding a wsdl file, "xmlns" attributes cause a search of the current namespace environment for an exact match on the URI. If a match cannot be found, an error is signalled. If a match is found, the XML name is interned in the corresponding Lisp package.

During output encoding, when the server is encoding a reply, or a client is encoding a request, or when encoding a wsdl file, create a top-level xmlns attribute from the first occurrence of each explicit namespace declaration in the namespace environment. A symbol in a package present in the current namespace environment is encoded as a qualified name.

### xmp-namespace-declaration

### Class

#### Package: net.xmp.soap

The Lisp class of a namespace declaration object.

### define-namespace

### Function

#### Package: net.xmp.soap

Arguments: package prefix uri &optional primary-p

This function stores a namespace definition that will be used in decoding or encoding SOAP messages. These definitions are created by explicit calls to this function or by mentions of namespaces in calls to define-namespace-map.

If the package and uri arguments are specified (that is, given a non-`nil` value), then a new namespace declaration object is created if it does not already exist.

If only the package or the uri argument is specified (that is, given a non-`nil` value), then find a matching namespace declaration object, if one exists.

If both package and uri are `nil`, then do nothing and return `nil`.

This function returns a `xmp-namespace-declaration` instance or `nil`.

The prefix argument is ignored when decoding SOAP messages. When encoding SOAP messages, only namespace definitions that have a non-`nil` prefix are used, definitions with a `nil` prefix are ignored and symbols in that package are encoded as unqualified names. The defined prefix is used in the xmlns declaration of the namespace. The prefixes mentioned in a specific XML context must be distinct or an error is signaled.

### delete-namespace

### Function

#### Package: net.xmp.soap

Arguments: package prefix uri

This function deletes any namespace declarations matching the arguments. Either package or uri must be non-`nil`, or no namespaces are deleted. If one is nil while the other is non-`nil`, then all namespaces with the non-`nil` component are deleted, that is, nil works as a wildcard when the other component is specified. Nothing will be deleted if only prefix is non-`nil`.

### Namespace variables, no longer supported

In an earlier version, the following variables had namespace specifications as values. All these variables are removed and namespaces are determined by the namespace operators described above.

- `*soap-namespaces*`
- `*wsdl-default-namespaces*`
- `*application-namespaces*`
- `*soap-namespaces-a*`
- `*soap-namespaces-b*`
- `*wsdl-1.1-namespaces*`
- `*wsdl-1.2-namespaces*`

## 10.3.3 Deducing the namespaces used in a WSDL file

The function decode-wsdl-namespaces returns information about the namespaces mentioned in a WSDL definition and it can generate a namespace specification based on some heuristic rules.

### decode-wsdl-namespaces

### Function

#### Package: net.xmp.soap

Arguments: &key file string uri map show

This function returns 4 values:

1. A namespace specification acceptable as the :namespaces argument
2. A list of unrecognized URIs
3. A list of missing namespaces
4. A list of ambiguous namespaces

file should be a string containing the path to a file. string should be a string containing a WSDL definition. uri should be the uri where a WSDL definition may be found. Only one of the above arguments should appear.

The map argument specifies a namespace map that determines the namespace mapping strategy. The default is `:wsdl1-prefix` defined as `(nil :wsdl1.1-namespaces :all ("wsdl-" nil :prefix))`. This definition searches in this order:

1. `:wsdl1.1`, `:wsdl1.2`, `:soap1.1`, `:soap1.2`, `:schema2001`, `:schema1999`
2. all namespace maps defined with define-namespace-map
3. all namespaces defined with define-namespace unmatched namespaces are assigned to a new package named "wsdl-NNN"

If the value of the show keyword argument is non-`nil`, it must be `t` or a stream. Then a readable version of the namespaces is printed to `*standard-output*` (when `t`) or to the stream.

When decode-wsdl-file is called with a namespaces argument of `:decode`, the function decode-wsdl-namespaces is called and if values 2 3 and 4 are `nil` the decode operation proceeds with the resulting namespace specification. If any of the values 2 3 or 4 are non-`nil`, the function signals an error.

## 10.4 Mapping SOAP Structures to CLOS classes

When the :object-class argument is specified to make-client-interface, a set of classes are generated from the type and element definitions in the WSDL file. Constructor and accessor functions are also generated, as well as object-oriented methods for calling SOAP methods.

### soap-object-class

### Class

#### Package: net.xmp.soap

Application may define a subclass with different slot values for class slots:

- reader-prefix: default is `:soap-get-`
- writer-prefix: default is `:soap-set-`

## 10.4.1 Generated Classes

Each complex type definition in the WSDL is mapped to a sub-class of the user-defined sub-class of `soap-object-class`. The Lisp name of the Schema type is also the name of the corresponding CLOS class.

## 10.4.2 Generated Accessors

The slot readers in the generated classes have names of the form

    <reader-prefix from object-class><converted SOAP sub-element name>

The slot writers in the generated classes have names of the form

    <writer-prefix from object-class><converted SOAP sub-element name>

The arguments to the slot writer are the standard CLOS writer arguments: new slot value, and instance.

## 10.4.3 Generated Constructors, Decoders, and Encoders

new-<converted SOAP type name> is an ordinary function with keyword arguments. The keyword argument names are the converted sub-element names of the complex type.

decode-<converted SOAP type name> is an ordinary function of one argument, the value returned by call-soap-method.

<prefix>encode is a generic function of one argument specialized on the `soap-object-class` of the SOAP complex type.

## 10.4.4 Call Wrapper Methods

These wrapper functions are generated when the `:message-method-prefix` option is non-`nil`.

      <message-method-prefix><converted SOAP message name>

The method takes positional arguments specialized on the SOAP structure classes defined for the corresponding message components.

## 10.4.5 Mapping SOAP Names to Lisp Names

The conversion of SOAP Schema names to Lisp symbols is controlled by the `:convert` argument to make-client-interface. Its value can be:

- `nil`: the case-sensitive SOAP name is used as the Lisp symbol name
- `:hyphen`: The SOAP name is hyphenated at case shift positions and downcased
- `:hyphen-if-ok`: if there are no apparent case folding conflicts, the SOAP names are hyphenated and downcased as above; otherwise, the case-sensitive SOAP name is used as the Lisp symbol name
- `:downcase`: the SOAP name is simply downcased.
- `:downcase-if-ok`: if there are no apparent case folding conflicts, the SOAP names are simply downcased; otherwise, the case-sensitive SOAP name is used as the Lisp symbol name

## 10.5 How to generate a SOAP client interface from a WSDL definition

In this section, we go through the steps needed to generate a client interface from a WSDL definition obtained from some outside source. We use the files AmazonS3.wsdl and AmazonS3.xsd as examples. The files were obtained from the web but copies are included in the Allegro CL distribution in examples/soap/ (included in an update released in early September, 2006).

(The following steps could be applied to the web version but the results may differ if the service definition has changed.)

In order to run the example, be sure that the SOAP module is laoded and that the :net.xmp.soap is used (otherwise package-qualify the symbols as necessary in the example code).

    (require :soap)
    (use-package :net.xmp.soap)

### Step 1: Determine the Namespace Requirements

    (soap-new-environment)
    (decode-wsdl-namespaces :file "AmazonS3.wsdl" :map nil :show t)

The first expression is optional. It may be a good idea to evaluate this expression if this example is repeated in the same Lisp invocation or if other WSDL files have been tried. The effect is to discard all SOAP definitions and start with a clean environment.

The second expressions parses the WSDL file and reports on the namespaces mentioned in the file. The show argument prints a readable summary of this information:

         #|
         Namespace map:
           (nil
            ("net.xmp.wsdl" "wsdl" "http://schemas.xmlsoap.org/wsdl/")
             ("net.xmp.wsdl.soap" "wsdl-soap"
              "http://schemas.xmlsoap.org/wsdl/soap/")
             ("net.xmp.schema" "xsd" "http://www.w3.org/2001/XMLSchema"))
         Other namespaces:
             "http://s3.amazonaws.com/doc/2006-03-01/")
         |#

The first section of the output labelled "Namespace map:" lists the namespaces that were recognized and are already mapped to Lisp packages because of built-in definitions or previous user definitions.

The next section labelled "Other namespaces:" lists the URLs of other namespaces mentioned in the WSDL. These will be mapped to generated packages by default, but it is good practice to define a fixed package for each namespace. This makes generated code more readable and gives consistent and comparable results from one run to the next.

Sometimes additional sections are listed to show ambiguous or unrecognizable namespaces. These situations may indicate an ill-formed WSDL. In most cases, if these sections appear customer service may need to intervene.

### Step 2: Define Application Namespaces

In this example, there is one namespace specific to this application.

    (define-namespace :aws "aws" "http://s3.amazonaws.com/doc/2006-03-01/")
    (define-namespace-map :awsmap nil '(:aws))

The first expression defines one namespace. The second expression defines a namespace map which is used to hold all the namespaces in the configuration of an application.

### Step 3: Decode the WSDL definition

    (setf def
        (decode-wsdl-file "AmazonS3.wsdl" :namespaces :awsmap :verbose t))

The above expression decodes the WSDL file and returns a wsdl-file-connector instance. We assign this to a variable since it will be needed in subsequent expressions.

    ; schemaLocation=AmazonS3.xsd was not included.

The above message indicates that something was not quite right during the decoding, but we forge ahead hoping for the best.

### Step 4: First Pass at Client Interface

    (make-client-interface def 0 t)

This expression generates a client definition for the first (zeroth) service definition in the previously decoded file. The generated code is directed to `*standard-output*`.

    Error: Cannot determine message type in (...)
       - type may be defined in included Schema.

But we cannot generate code because there is some missing information.

### Step 5: Decode the WSDL definition again

The included file appears to be necessary in order to decode and analyze the WSDL definition fully. We need to tell the decoder how to find the included text.

    (setf def (decode-wsdl-file "AmazonS3.wsdl" :namespaces :awsmap
                                :verbose t :include 'wsdl-include-file))

The above expression specifies the function wsdl-include-file to map the schemaLocation attribute to a file in the local file system.

    ; schemaLocation=AmazonS3.xsd included with wsdl-include-file

This time the message confirms that a second Schema was included.

### Step 6: Second Pass at Client Interface

    (make-client-interface def 0 "a-client.cl")

This time, we direct the output of the generated code to a file. The returned value is a summary of the generated definitions.

         ((("Output in file:" :key :file) "a-client.cl")
          (("Defined functions:" :key defun)
           (client-18 "Send client message ListAllMyBuckets "
            aws:ListAllMyBuckets)
           (client-17 "Send client message ListBucket " aws:ListBucket)
           (client-25 "Send client message DeleteObject " aws:DeleteObject)
           (client-14 "Send client message PutObjectInline "
            aws:PutObjectInline)
           (client-1 "Send client message PutObject " aws:PutObject)
           (client-12 "Send client message GetObjectExtended "
            aws:GetObjectExtended)
           (client-5 "Send client message GetObject " aws:GetObject)
           (client-9 "Send client message SetBucketAccessControlPolicy "
            aws:SetBucketAccessControlPolicy)
           (client-8 "Send client message SetObjectAccessControlPolicy "
            aws:SetObjectAccessControlPolicy)
           ...)
          (("Defined SOAP elements:" :key define-soap-element)
           aws:ListAllMyBucketsResponse aws:ListAllMyBuckets
           aws:ListBucketResponse aws:ListBucket aws:DeleteObjectResponse
           aws:DeleteObject aws:PutObjectInlineResponse aws:PutObjectInline
           aws:PutObjectResponse ...)
          (("Defined SOAP types:" :key define-soap-type)
           aws:ListAllMyBucketsList aws:ListAllMyBucketsResult
           aws:ListAllMyBucketsEntry aws:ListBucketResult aws:ListEntry
           aws:PutObjectResult aws:GetObjectResult aws:AccessControlPolicy
           aws:AccessControlList ...)
          (("Defined packages:" :key defpackage) :keyword :common-lisp-user :aws
           #:aws #:common-lisp-user)
          (("Lisp package of generated file:" :key in-package)
           #:common-lisp-user)
          (("Other entries:" :key define-namespace-map) :client-namespaces)
          (("Other entries:" :key defvar) *client-service-url*))

### Step 7: Try the Interface

In order to try the interface, we need to compile and load the generated code.

    (load (compile-file "a-client.cl"))
    (setf *soap-client-debug* :stop)
    (client-7 :Bucket "bbb" :AWSAccessKeyId "id" :Timestamp 123)

The first expression compiles and loads the generated code. It is not necessary to compile, but the compiler does identify many problems in code before it is run.

The second expression informs the SOAP runtime to stop before actually sending a message to the server, and print a formatted version of the SOAP message for review.

### Refine the Interface

At this point, the generated code may be tweaked in various ways by generating the code again with additional parameters to make-client-interface:

- change the names of the client calls with the prefix and suffix options
- generate CLOS classes with the object-class option
- map mixed-case SOAP names to hyphenated Lispy names
- adjust packages

## 10.5.1 Combining Several WSDL Definitions in one Lisp Image

When several WSDL definitions must be combined into one Lisp image, there may be several issues that must be resolved before a working application is generated:

The distinct WSDL definitions may use identical names to denote distinct types or methods. This situation may be corrected by decoding the files into distinct Lisp packages and mapping namespaces appropriately. The prefix and suffix options may also be useful in keeping names distinct.

The distinct WSDL definitions may duplicate Schema elements by explicit repetition or by including identical definitions. The :redef argument to make-client-interface provides several strategies for handling this situation.

## 10.6 Customizing Generated Code

### wsdl-generate-code

### Generic Function

#### Package: net.xmp.soap

Arguments: conn mode info op &rest args

This method may be used to modify the code generated by make-client-interface and make-server-interface.

The default method specialized on `(wsdl-file-connector t t t)` simply emits the cons of op and args.

If the op argument is null and there is only exactly one element in args, then the entire form is that single element.

The method may return two values when it is called for a top-level form. In that case the second value may be a string or a list of strings. The strings are emitted as comments before the form.

An application may define a sub-class of `wsdl-file-connector` and some more specific methods to alter the generated code. The application class is specified in the call to decode-wsdl-file.

The method is called with the following arguments during code generation:

mode | info | operator | comments
`:client` | `:top-level` | defun | client message function
`:client` | `nil` | soap-message-client |
`:server` | `:top-level` | defun | new server function
`:server` | `:top-body` | defun | method definition skeleton
`:server` | `nil` | soap-message-server |
`:object-class` | `:top-level` | defclass |
`:object-new` | `:top-level` | defun |
`:object-decoder` | `:top-level` | defmethod |
`:object-encoder` | `:top-level` | defmethod |
`:object-type` | `:top-level` | defclass |
`:object-wrapper` | `:top-level` | defmethod |
`:sever` | `:method-body` | --- | called to emit default comment "INSERT BODY HERE"

### wsdl-post-process

### Generic Function

#### Package: net.xmp.soap

Arguments: conn defs

This function is called after all the types, elements, and message functions have been generated, but not yet written to the output file. The built-in method is specialized on (t t) and does nothing.

The defs argument is a list of items of the form `(form comment ...)`. The order of the items in the list is the order in which the forms will be written into the output file.

An application may add a primary or an `:around` method to manipulate the definitions or to add additional code to the output file.

To add a form to the output, call the function: wsdl-add-form with arguments `conn form &rest comments`.

### wsdl-maybe-conflicts

### Generic Function

#### Package: net.xmp.soap

Arguments: conn

The value returned by this function is one of the following:

- :unknown: no information is available
- `nil`: no conflicts detected
- `(x y z...)`: a list of symbols or strings that identify symbols that may cause problems during case-folding.

### wsdl-add-form

### Generic Function

#### Package: net.xmp.soap

Arguments: conn form &rest comments

The form is added at the end of the code generated by make-client-interface or make-server-interface. If comments are specified, they must be strings. Comments are inserted before the form in the generated file.

Code can only be added at the end of the generated file. If it is necessary to modify code at the beginning of the file, it must be done by adding a wsdl-generate-code method that modifies one of the forms emitted at the beginning of the file.

## 11.0 Headers

If a client message must be sent with one or more SOAP header elements, the elements must be built with make-soap-header and saved in the connection instance created with soap-message-client. Every time a SOAP message is sent, the current collection of headers is included in the message as a single SOAP Header element.

If a SOAP server method must examine the content of SOAP header elements when handling a SOAP message, the accessor soap-message-headers may be used to extract the list of header elements.

### make-soap-header

### Generic Function

#### Package: net.xmp.soap

Arguments: conn element-spec &rest args

The arguments are as for call-soap-method, but instead of sending a message, this method returns an object of class `soap-header` which contains an encoded representation of the header element.

If the header element must have a "mustUnderstand" attribute, the attribute may be specified as a :must-understand option or included in the :attributes option of the element definition.

### soap-add-header

### Generic Function

#### Package: net.xmp.soap

Arguments: conn header &key after before reset

The header argument must be an instance of the class `soap-header`. The method adds the header to the list of headers that will be sent with the next message.

The before and after arguments may be `nil` or headers previously added.

If reset is non-`nil`, then any previously added headers are discarded.

### soap-must-understand

### Generic Function

#### Package: net.xmp.soap

Arguments: conn element-name

When a reply message is decoded, and a "mustUnderstand" attribute with value "1" is present, then this method is called.

The default method behavior depends on the setting of the `:must-understand` flag in the connection instance. The following settings produce the indicated behavior:

- `:warn` - print a warning and accept the header
- `nil` - accept the header silently
- Any other value - signal an error

### soap-message-headers

### Generic Function

#### Package: net.xmp.soap

Arguments: conn

When conn is an instance of soap-connector, this accessor method returns a list of all the header elements in the SOAP message.

## 12.0 Faults and Errors

All the warnings and errors signalled by the SOAP module are described by the following hierarchy:

       xmp-warning hierarchy:

                simple-warning
                       xmp-warning
                                 xmp-syntax
                                 xmp-redefinition
                                 soap-decode-warning

       xmp-condition hierarchy:

                error
                   xmp-condition
                         xmp-client-condition
                             soap-client-error
                                  soap-client-fault
                         xmp-server-condition
                             soap-server-error
                                  soap-server-fault
                         soap-mismatch
                         soap-must-understand

## 13.0 Index

- `*application-namespaces*` (Removed variable, see this note)
- call-soap-method (Generic Function)
- decode-wsdl-at-uri
- decode-wsdl-file
- decode-wsdl-namespaces
- decode-wsdl-source
- decode-wsdl-string
- define-namespace (Function)
- define-namespace-map (Function)
- define-soap-element (Generic Function)
- define-soap-type (Function)
- define-namespace-map (Function)
- disable-soap-server (Function)
- enable-soap-server (Function)
- encode-wsdl-file (Function)
- make-client-interface
- make-server-interface
- make-soap-header (Generic Function)
- soap-add-header (Generic Function)
- soap-alist-to-plist (Function)
- soap-binding-name (Generic Function)
- `*soap-client-debug*` (Variable)
- soap-encode-object (Generic Function)
- soap-export-method (Generic Function)
- soap-get-attribute (Generic Function)
- soap-get-attributes (Generic Function)
- soap-invoke-method (Generic Function)
- soap-make-fault (Function)
- soap-message-body (Generic Function)
- soap-message-client (Function)
- soap-message-headers (Generic Function)
- soap-message-server (Function)
- soap-must-understand (Generic Function)
- soap-new-environment (Function)
- `soap-object-class` (Class)
- soap-port-name (Generic Function)
- `*soap-namespaces*` (Removed variable, see this note)
- `*soap-namespaces-a*` (Removed variable, see this note)
- `*soap-namespaces-b*` (Removed variable, see this note)
- soap-result-only (Generic Function)
- soap-result-pair (Generic Function)
- soap-result-part (Generic Function)
- soap-result-string (Generic Function)
- soap-result-typed (Generic Function)
- `*soap-server*` (Variable)
- `*soap-server-debug*` (Variable)
- soap-server-message-action (Generic Function)
- soap-server-message-method (Generic Function)
- soap-server-message-return (Generic Function)
- soap-server-message-signature (Generic Function)
- soap-service-name (Generic Function)
- soap-sub-element-content (Function)
- soap-version
- start-soap-server
- stop-soap-server
- wsdl-add-form (Generic Function)
- `*wsdl-default-namespaces*` (Removed variable, see this note)
- `wsdl-file-connector`
- wsdl-generate-code (Generic Function)
- wsdl-include-file
- wsdl-include-url
- wsdl-maybe-conflicts
- wsdl-post-process
- wsdl-service-names
- `*wsdl-1.1-namespaces*` (Removed variable, see this note)
- `*wsdl-1.2-namespaces*` (Removed variable, see this note)
- `xmp-namespace-declaration`
- `xmp-namespace-map`

Copyright (c) 1998-2019, Franz Inc. Oakland, CA., USA. All rights reserved.
This page was not revised from the 8.2 page.
Created 2012.5.30.

ToC | DocOverview | CGDoc | RelNotes | FAQ | Index | PermutedIndex
| Allegro CL version 9.0 Moderate update since 9.0 release. 8.2 version