2 Defining XML Types

"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.

2.1 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))

2.2 Validating Element Constructors

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.

2.3 Compiling an XML Schema

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:

name-symbol is a name to be used for the module name and in the file name. For example, the bibtex like Schema "sbib" uses sbib as it's name. A module named sbib is produced, in a file "sbib.ss".
the-schema must be an expression which evaluates to an XML Schema
prefix may be a prefix (symbol) used for the constructor and predicate names, or may be #f, indicating that no prefix is used. For example, the HTML constructor functions in WebIt! use "h4" as the prefix.

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.

Last modified: Sunday, January 30th, 2005 1:57:37pm
HTML generated using WebIt!.