WebReference.com - Chapter 30 of Curl Programming Bible, from John Wiley & Sons (6/8) | WebReference

WebReference.com - Chapter 30 of Curl Programming Bible, from John Wiley & Sons (6/8)

To page 1To page 2To page 3To page 4To page 5current pageTo page 7To page 8
[previous] [next]

Curl Programming Bible, chapter 30

Creating Custom Mappings

The Curl SOAP support provides some conversion between XML types and Curl types. The conversions are listed in Table 30-1. If you need a conversion not listed in the table, you must create a custom mapping.

Creating a custom mapping for a simple type

Suppose you want to create a mapping between the Curl type DateTime and the XML type dateTime . First, you need to create procedures to encode the Curl type into the XML type and decode the XML type into the Curl type. These procedures must be of type XMLMarshaler and XMLUnmarshaler.

NOTE: It is not always necessary to create both a marshaler and an unmarshaler proce-dure. If only input arguments require the mapping, only a marshaler is needed. If only output arguments require the mapping, only an unmarshaler is needed.

The unmarshaler is straightforward because the Curl DateTime constructor accepts strings that have the lexical representation of the XML type dateTime. So we take the XML representation of dateTime and pass it to the Curl DateTime constructor. Here is the code for the unmarshaler:

|| decode an XML dateTime into a Curl DateTime
|| procedure must be of type XMLUnmarshaler
{define-proc public {date-time-unmarshaler
                        mapper:XMLCurlMappingRegistry,
                        encoding-style:String,
                        input:XMLInputStream
                    }:any
     let xml-token:XMLToken={input.read-one}
    {type-switch xml-token
     case char-data:XMLCharacters do
        {return {DateTime char-data.characters}}
     else
        {error "expected XMLCharacters"}
    }
}

NOTE: The Curl DateTime type has a limited range of dates that it can represent. For instance, it cannot represent dates before the year 1970. So, the Curl DateTime constructor may throw an error on a valid XML dateTime value if it cannot be represented by the DateTime type.

The unmarshaler procedure is passed an XMLInputStream. It reads the next XMLToken from the XMLInputStream. It expects the XMLToken to be of type XMLCharacters. If it is, it passes the string of characters to the DateTime constructor and returns the resulting value.

The marshaler needs to do some extra work because the output of Curl's DateTime.to-String method is a little different from the canonical representation of XML's dateTime. You do this work in a procedure named xml-canonicalize-date-time. We do not present it here, but it is contained in the example on the accompanying Web Site. Here's the code for the marshaler:

|| encodes a Curl DateTime to XML dateTime
|| procedure must be of type XMLMarshaler
{define-proc public {date-time-marshaler
                        mapper:XMLCurlMappingRegistry,
                        encoding-style:String,
                        value:any,
                        xos:XMLOutputStream,
                        include-type-attribute?:bool,
                        xsi:String
                    }:void
    {xos.write-one 
        {new XMLCharacters,
            {xml-canonicalize-date-time (value asa DateTime)}
        }
    }
}

The marshaler is passed an XMLOutputStream and a value that is a DateTime. The date-time-marshaler must declare the value to be of type any so its signature matches XMLLMarshaler. When date-time-marshaler is called, value will be of type DateTime. The marshaler calls the xml-canonicalize-date-time procedure to convert DateTime value to its canonical XML representation, and then writes the resulting string as character data (by using the XMLCharacters subclass of XMLToken ) to the XMLOutputStream.

You need to do a few things so the Curl SOAP support can locate this custom mapping:

Here is the code that does this:

|| create a registry
{let my-registry:XMLCurlMappingRegistry={new XMLCurlMappingRegistry}}
|| register the mapping
{my-registry.map-types
    Soap-1-1-HttpOperation.soap-encoding,,
    {new XMLName,
        xsd,
        "dateTime"},
    DateTime,
    date-time-marshaler,
    date-time-unmarshaler
}
|| include the registry as a keyword argument on the call method
{let anys:{Array-of any}={echo-date.call date-time, registry=my-registry}}

Type mappings are registered in an XMLCurlMappingRegistry using the map-type method. The argument to the map-type method includes the XML type and Curl type of the mapping as well as the marshaler and unmarshaler that convert between the types.

The registry must be included in the SOAP call using the registry keyword argument.

NOTE: If a call uses multiple custom mappings, create one XMLCurlMappingRegistry instance, register all the mappings in the registry, and pass the registry in the Soap-1-1-HttpOperation.call method.

An example incorporating this custom mapping (echo-date.curl) is on the accompanying Web site.


To page 1To page 2To page 3To page 4To page 5current pageTo page 7To page 8
[previous] [next]

Created: August 14, 2002
Revised: August 14, 2002

URL: http://webreference.com/programming/curlbible/chap30/6.html