3. SOAP Packages

Every SOAP package in YAZ is represented as follows:

#include <yaz/soap.h>

typedef struct {
    char *fault_code;
    char *fault_string;
    char *details;
} Z_SOAP_Fault;

typedef struct {
    int no;
    char *ns;
    void *p;
} Z_SOAP_Generic;

#define Z_SOAP_fault 1
#define Z_SOAP_generic 2
#define Z_SOAP_error 3
typedef struct {
    int which;
    union {
        Z_SOAP_Fault   *fault;
        Z_SOAP_Generic *generic;
        Z_SOAP_Fault   *soap_error;
    } u;
    const char *ns;

The fault and soap_error arms both represent a SOAP fault - struct Z_SOAP_Fault. Any other generic (valid) package is represented by Z_SOAP_Generic.

The ns as part of Z_SOAP is the namespace for SOAP itself and reflects the SOAP version. For version 1.1 it is http://schemas.xmlsoap.org/soap/envelope/, for version 1.2 it is http://www.w3.org/2001/06/soap-envelope.

int z_soap_codec(ODR o, Z_SOAP **pp,
                 char **content_buf, int *content_len,
                 Z_SOAP_Handler *handlers);

The content_buf and content_len is XML buffer and length of buffer respectively.

The handlers is a list of SOAP codec handlers - one handler for each service namespace. For SRU SOAP, the namespace would be http://www.loc.gov/zing/srw/v1.0/.

When decoding, the z_soap_codec inspects the XML content and tries to match one of the services namespaces of the supplied handlers. If there is a match. a handler function is invoked which decodes that particular SOAP package. If successful, the returned Z_SOAP package will be of type Z_SOAP_Generic. Member no is set the offset of the handler that matched; ns is set to namespace of the matching handler; the void pointer p is set to the C data structure associated with the handler.

When a NULL namespace is met (member ns below), that specifies end-of-list.

Each handler is defined as follows:

typedef struct {
    char *ns;
    void *client_data;
    Z_SOAP_fun f;
} Z_SOAP_Handler;

The ns is the namespace of the service associated with handler f. The client_data is user-defined data which is passed to the handler.

The prototype for a SOAP service handler is:

int handler(ODR o, void * ptr, void **handler_data,
            void *client_data, const char *ns);

The o specifies the mode (decode/encode) as usual. The second argument, ptr, is a libxml2 tree node pointer (xmlNodePtr) and is a pointer to the Body element of the SOAP package. The handler_data is an opaque pointer to C definitions associated with the SOAP service. The client_data is the pointer which was set as part of the Z_SOAP_handler. Finally, ns is the service namespace.