Hi Folks,
Recall that with XML Schema you can create a complexType that restricts another complexType. That “derive-by-restriction” capability is useful when you have two levels of syntax, one level restricting the other.
Lisp provides a neat example of multiple levels of syntactic rules. The Lisp language specification has a syntactic rule which says that lists can contain anything. The specification then layers on top a second syntactic rule which requires that lists specifically start with a symbol.
Here is a list that is valid according to the first level of syntax:
(“Hello, world” 10)
but it is invalid per the second level of syntax (i.e., the list does not start with a symbol – a string is not a symbol).
Terminology: A list that conforms to the first level of syntax is called a symbolic-expression (s-expression). A list that conforms to the second level of syntax is called a Lisp form.
A Lisp form is a restricted s-expression:
I converted these concepts over to XML and XML Schema. The result is a beautiful example of restriction. Here is the complexType for the first level of syntax (s-expression):
<xs:complexType name="s-expression">
<xs:choice>
<xs:element name="atom" type="atom" />
<xs:element name="empty-list" type="empty-list" />
<xs:element name="non-empty-list" type="non-empty-list" />
</xs:choice>
</xs:complexType>
The following is the complexType for the second level of syntax (Lisp form). Notice that it restricts the s-expression.
<xs:complexType name="Lisp-form">
<xs:complexContent>
<xs:restriction base="s-expression">
<xs:choice>
<xs:element name="atom" type="atom" />
<xs:element name="empty-list" type="empty-list" />
<xs:element name="non-empty-list"
type="non-empty-list-that-starts-with-a-symbol" />
</xs:choice>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
By the way, I believe that the XML language specification defines only one level of syntax. Do you agree?
For those that are interested in more details, I have included below the precise definitions of s-expression and Lisp form, and the XML Schemas plus sample XML instances.
/Roger
In the first level of syntax, symbolic-expressions (s-expressions) are defined:
Note: the definitions come from the excellent book: Practical Common Lisp by Peter Seibel.
This list is an s-expression: (“Hello, world” 10 foo)
In the second level of syntax, Lisp forms are defined:
A Lisp form is a restricted s-expression. Specifically, lists must begin with a symbol. The above example is a valid s-expression but an invalid Lisp form. Here is a valid Lisp form: (foo 10)
Here is an XML Schema for s-expressions:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="s-expression" type="s-expression" />
<xs:complexType name="s-expression">
<xs:choice>
<xs:element name="atom" type="atom" />
<xs:element name="empty-list" type="empty-list" />
<xs:element name="non-empty-list" type="non-empty-list" />
</xs:choice>
</xs:complexType>
<xs:complexType name="empty-list">
<xs:choice>
<xs:sequence>
<xs:element name="left-parenthesis" type="empty" />
<xs:element name="right-parenthesis" type="empty" />
</xs:sequence>
</xs:choice>
</xs:complexType>
<xs:complexType name="non-empty-list">
<xs:sequence>
<xs:element name="left-parenthesis" type="empty" />
<xs:element name="first" type="element"/>
<xs:element name="rest" type="rest" minOccurs="0" />
<xs:element name="right-parenthesis" type="empty" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="rest">
<xs:sequence>
<xs:element name="first" type="element"/>
<xs:element name="rest" minOccurs="0" type="rest"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="element">
<xs:sequence>
<xs:element name="element" type="s-expression" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="atom">
<xs:choice>
<xs:element name="number" type="xs:double" />
<xs:element name="string">
<xs:simpleType>
<xs:restriction base="xs:string">
<!-- Incomplete -->
<xs:pattern value='"[a-zA-Z][a-zA-Z0-9\-, ]*"' />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="symbol" type="symbol" />
</xs:choice>
</xs:complexType>
<xs:simpleType name="symbol">
<xs:restriction base="xs:string">
<!-- Incomplete -->
<xs:pattern value='[a-zA-Z][a-zA-Z0-9\-]*' />
</xs:restriction>
</xs:simpleType>
<xs:complexType name="empty" />
</xs:schema>
Here is a sample s-expression, expressed in XML:
<s-expression>
<non-empty-list>
<left-parenthesis/>
<first>
<element>
<atom>
<string>"Hello, world"</string>
</atom>
</element>
</first>
<right-parenthesis/>
</non-empty-list>
</s-expression>
Here is an XML Schema for Lisp forms:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="s-expression.xsd" />
<xs:element name="Lisp-form" type="Lisp-form" />
<xs:complexType name="Lisp-form">
<xs:complexContent>
<xs:restriction base="s-expression">
<xs:choice>
<xs:element name="atom" type="atom" />
<xs:element name="empty-list" type="empty-list" />
<xs:element name="non-empty-list"
type="non-empty-list-that-starts-with-a-symbol" />
</xs:choice>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="non-empty-list-that-starts-with-a-symbol">
<xs:complexContent>
<xs:restriction base="non-empty-list">
<xs:sequence>
<xs:element name="left-parenthesis" type="empty" />
<xs:element name="first" type="symbol-element"/>
<xs:element name="rest" type="rest" minOccurs="0" />
<xs:element name="right-parenthesis" type="empty" />
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="symbol-element">
<xs:complexContent>
<xs:restriction base="element">
<xs:sequence>
<xs:element name="element" type="symbol-s-expression" />
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="symbol-s-expression">
<xs:complexContent>
<xs:restriction base="atom-s-expression">
<xs:choice>
<xs:element name="atom" type="symbol-atom" />
</xs:choice>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="atom-s-expression">
<xs:complexContent>
<xs:restriction base="s-expression">
<xs:choice>
<xs:element name="atom" type="atom" />
</xs:choice>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="symbol-atom">
<xs:complexContent>
<xs:restriction base="atom">
<xs:choice>
<xs:element name="symbol" type="symbol" />
</xs:choice>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:schema>
Here is a sample Lisp form, expressed in XML:
<Lisp-form>
<non-empty-list>
<left-parenthesis/>
<first>
<element>
<atom>
<symbol>foo</symbol>
</atom>
</element>
</first>
<rest>
<first>
<element>
<atom>
<number>10</number>
</atom>
</element>
</first>
</rest>
<right-parenthesis/>
</non-empty-list>
</Lisp-form>