"Defining XML types" in WebIt! creates constructor and predicate functions for XML elements and attributes. Two facilities are provided to define XML types (element and attributes). First, one can directly use the define-element and define-attribute syntax. Or one can "compile" an RS-XML representation of an XML Schema into a module containing the generated constructor and predicate functions.
The define-element
syntax allows one to (optionally) write "validating" element
constructors: a set of patterns can be provided, which will be used to validate
each element which is constructed.
define-element
and define-attribute
These two syntactic forms can be used to define elements and attributes. These forms must be used in a position where a define is allowed. (For instance, these can be used to define types which are local to a "stylesheet"-- i.e. elements which are generated and transformed within the stylesheet, but are not visible outside the transformations.)
In it's simplest form, define-element
can be used to define a locally named element, with no validation:
(define-element box)
This will produce a constructor function box
and a predicate box?
.
We can indicate that the box
element is part of an XML namespace:
(define-element (box http://celtic.benderweb.net/schemas/pieces))
Sometimes the name of an element may conflict with other Scheme names. It can be convenient to prefix the name of the element:
(define-element (j:box http://celtic.benderweb.net/schemas/pieces))
This will produce an element constructor function j:box
and a predicate j:box?
. But it is interesting to note that the j:
is not part of the XML type names: the local name for this element is still "box" and the expanded name is "{http://celtic.benderweb.net/schemas/pieces}:box"
.
The basic syntax of define-element is:
def-ele ::= (define-element tag)
| (define-element (tag ns-uri))To define a color attribute, one write:
(define-attribute color)
This defines a keyword color:
(which can be used in invocations of an element
constructor function), an attribute constructor function &color
, and a predicate function &color?
.
As with elements, one can specify a prefix for theses Scheme names:
(define-attribute j:color)
And one can place the color attribute in an XML namespace:
(define-attribute (color http://celtic.benderweb.net/schemas/pieces))
The syntax of define-attribute
is:
def-attr ::= (define-attribute tag)
| (define-attribute (tag ns-uri))Using the same pattern matching used in the xml-rules
form, one can specify patterns to be used to validate an element being constructed.
Below, we define a table of contents element (the toc
element), which must consist of a sequence of poem
elements, with specific attributes:
(define-element toc (validate (toc (poem title: t poet: a tag: m . rest) ...)))
When an toc
element is being constructed, it must match a pattern in the validate clause (or the form (validate pat ...)
). If the new element does not match any patterns, an error is signalled.
The full syntax of define-element
is:
def-ele ::= (define-element tag)
| (define-element (tag ns-uri))
| (define-element tag (validate pat ...))
| (define-element (tag ns-uri) (validate pat ...))Tag and ns-uri must be symbols.
A facility is provided to extract element and attribute type definitions from a
schema, and to produce a module containing the corresponding element and attribute
constructor functions, predicates and keywords. (The compiler in fact produces define-element
and define-attribute
forms for each type in the schema.)
In RS-XML notation, the basic form of a schema is:
(xsd:schema type-decl ...)
Where a type declaration is any of the XML Schema elements. The only significant elements are xsd:element
and xsd:attribute
. These will cause WebIt! to generate
element or attribute constructors and predicates.
One can indicate an XML namespace for the elements and attributes defined in a
schema by adding the xsd:targetNamespace
attribute to the schema element:
(xsd:schema
xsd:targetNamespace: "http://celtic.benderweb.net/schemas/pieces"
... declarations ...
)When defining elements and attributes, WebIt! allows one to specify as as many/few constraints as desired by the programmer. One can write a (fairly) complete element type definition:
(xsd:element xsd:name: "SCSCFInfo" (xsd:complexType (xsd:sequence (xsd:element name: "SCSCFCapabilities" xsd:type: "xsd:string") (xsd:element xsd:name: "SCSCFaddress" xsd:type: "ipAddr"))))
This specifies that the SCSCFInfo
element must contain an ordered sequence of two other elements: SCSCFCapabilities
and SCSCFaddress
.
Or, one can specify no constraints, writing:
(xsd:element xsd:name: "SCSCFInfo")
Similarly attributes may be defined:
(xsd:attribute xsd:name: "address" xsd:type: "string")
but the type may be omitted:
(xsd:attribute xsd:name: "address")
The function which translates a schema in to a Scheme module is compile-schema:
(compile-schema name-symbol the-schema prefix)
where:
If a "target namespace" has been specified in the schema, the compiler will also generate a namespace variable: <name>-ns-url, which will be bound to the namespace uri (a string). For example, sbib-ns-url.