[cl-soap-devel] XSD Templates

Sven Van Caekenberghe scaekenberghe at common-lisp.net
Sun Oct 2 11:51:30 UTC 2005


After struggling with the XSD typing system for some time,
I think I finally 'solved' the problem (as far as the way Google is  
using XSD for their AdWords API).

Internally, a WSDL document is parsed.
Inside the WSDL <types> tag, a XSD <schema> could be embedded.

The parse-xsd code turnes the supported XSD tags into a CL object model.

Before using that model, it is simplified by transforming it into a  
so called XSD template.

Such a template looks like this:

(1
"getAllAdWordsCampaignsResponse"
(+ "getAllAdWordsCampaignsReturn"
     (1 "id" :INT)
     (? "name" :STRING)
     (? "status" :STRING)
     (? "startDate" :DATETIME)
     (? "endDate" :DATETIME)
     (? "dailyBudget" :LONG)
     (? "optInSearchNetwork" :BOOLEAN)
     (? "optInContentNetwork" :BOOLEAN)
     (* "campaignNegativeKeywords"
        (1 "id" :LONG)
        (1 "adGroupId" :INT)
        (? "exemptionRequest" :STRING)
        (? "criterionType" :STRING)
        (? "language" :STRING)
        (? "status" :STRING)
        (? "negative" :BOOLEAN)
        (? "destinationUrl" :STRING)
        (? "type" :STRING)
        (? "minCpc" :LONG)
        (? "maxCpc" :LONG)
        (? "text" :STRING))
     (? "languageTargeting" (* "languages" :STRING))
     (? "geoTargeting" (* "countries" :STRING) (* "regions" :STRING)  
(* "metros" :STRING) (* "cities" :STRING))))

The syntax/sematics of which are defined as:

;; ELT = ( <multiplicity> "element-name" [ :primitive | ELT* ] )
;; where <multiplicity> is 1, ?, + or * and :primitive is a XSD  
primitive type keyword
;; all element types are resolved into primitives or sequences of sub  
elements
;; elements without contents are also possible

Three main functions are using the XSD template system:

- the code to document interpreted types, describe-xsd[-element]  
(also used by describe-wsdl-soap),
   that prints out the lisp style sexpr templates used for input/ 
output binding
- the code to bind an input binding sexpr into lxml, bind-element
- the code to resolve an output binding lxml into sexpr, resolve-element

The sexpr template for the above XSD template looks like this:

(getAllAdWordsCampaignsResponse
   (getAllAdWordsCampaignsReturn (
     ("id" :INT) 1
     ("name" :STRING) ?
     ("status" :STRING) ?
     ("startDate" :DATETIME) ?
     ("endDate" :DATETIME) ?
     ("dailyBudget" :LONG) ?
     ("optInSearchNetwork" :BOOLEAN) ?
     ("optInContentNetwork" :BOOLEAN) ?
     (campaignNegativeKeywords (
       ("id" :LONG) 1
       ("adGroupId" :INT) 1
       ("exemptionRequest" :STRING) ?
       ("criterionType" :STRING) ?
       ("language" :STRING) ?
       ("status" :STRING) ?
       ("negative" :BOOLEAN) ?
       ("destinationUrl" :STRING) ?
       ("type" :STRING) ?
       ("minCpc" :LONG) ?
       ("maxCpc" :LONG) ?
       ("text" :STRING) ? ) * )
     (languageTargeting
       ("languages" (:STRING) * )) ?
     (geoTargeting
       ("countries" (:STRING) * )
       ("regions" (:STRING) * )
       ("metros" (:STRING) * )
       ("cities" (:STRING) * )) ? ) + )) 1

An actual sexpr for the above sexpr template looks like this:

("getAllAdWordsCampaignsResponse"
(("getAllAdWordsCampaignsReturn"
    ("id"
     5631435
     "name"
     "Campaign #1"
     "status"
     "Active"
     "startDate"
     3335857874
     "endDate"
     3502857599
     "dailyBudget"
     1000000
     "optInSearchNetwork"
     T
     "optInContentNetwork"
     T
     "languageTargeting"(google::|email| "foo")
     (("languages" "en") ("languages" "nl"))
     "geoTargeting"
     (("countries" "BE") ("countries" "NL"))))))

At the moment, all test cases work, input and output is symmetrical,  
and the code in of better quality.

Hopefully independent testing will concur ;-)

Sven






More information about the cl-soap-devel mailing list