[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