S-expressions for XML documents

and for XML Schema components

C. M. Sperberg-McQueen

31 July 2001

Status of this document

This document represents the views of its author, and not necessarily those of his employer, colleagues, friends, or associates. It has no official standing whatever.
It is also not complete. Currently, it has a sketch of two notations for XML instances, represented as S-expressions, but nothing much about the actual components of an XML Schema. To do:
  • translate the structure of each XML Schema component into an equivalent S-expression structure
  • define Lisp functions to calculate all the interesting properties of the post-schema-validation infoset, in particular validity
  • provide examples of the schema components and the validation functions
  • accept Tim Berners-Lee's challenge to translate the infoset not only in to S-expressions but also into N3 notation


This document describes a simple visible representation of XML Schema components and provides a machine-processable translation of many of the definitions of technical terms provided by the W3C XML Schema Recommendation. The goals are
It is intended, in the first instance, as a way for the author to study XML Schema and understand the XML Schema: Formal Description document. If it proves useful for other tasks as well, so much the better. Efficiency in the implementation, in particular, is a non-goal.
The first three sections of the document describe the notation used. First there is a brief description of Lisp S-expressions. There follow two sections describing the use of S-expressions to represent XML documents and to represent information items and properties. These are essential for understanding the rest of the document, which consists [will consist] of applying these notations to A final section defines some utility functions which are not part of the Lisp language.
No discussion is given here about the process of translating from the XML transfer syntax defined in the XML Schema spec to the component level.

1. Notation

We use Lisp S-expressions to represent XML Schema components, XML documents and their parts, and XML information sets, and we use standard Lisp functions to extract subexpressions from them.
Definitions of the syntax of S-expressions can be found in any introductory Lisp or Scheme textbook. [At the moment, we have endeavored to use only constructs which are legal both in Scheme and in other Lisp systems, or to provide both Lisp and Scheme definitions where some constructs have different syntax. The Lisp used is GNU Emacs Lisp.]
[A definition of the syntax of S-expressions, or at least the set of expressions used here, may be inserted later. In the meantime, just check a textbook.]
[Don't have a textbook handy? Here is a BNF, using the syntax defined in the XML spec.]
s-expression ::= atom | list
list         ::= '(' (s-expression S)* ')'
atom         ::= STRING | NUMBER | SYMBOL | quoted
STRING       ::= '"' ([^"] | '\"')* '"'
NUMBER       ::= ([+-])? [0-9]+ ('.')?
SYMBOL       ::= (([a-zA-Z0-9-+=*/_~!@$%^&:<>{}]+) - NUMBER)
quoted       ::= '(quote' s-expression ')'
               | "'" s-expression
Readers who don't know Lisp should know that function invocations in Lisp look like (and are) lists whose first element is the name of the function being invoked. So (car foo) is, in the right context, not only a list with a first element of car and a second element of foo (and a third element which is the empty list — if this puzzles you and you don't want to just live with it, you do need to skim a Lisp textbook), but also an invocation of the function car on the argument foo.
The non-Lisp reader should also know that the functions car and cdr are used to extract from a list the first element of the list, and the rest of the list, respectively.[1] The invocation (car (a b c d)) yields a and (cdr (a b c d)) yields (b c d). Various shorthand functions for the composition of car and cdr are available: (cadr (a b c d)) is the same as (car (cdr (a b c d))) and yields b, while (cdddr (a b c d)) is the same as (cdr (cdr (cdr (a b c d)))) and yields (d), and so on. I'll use these functions without much comment from here on.
Comments are not included in the grammar above, because they are not part of the S-expression. Comments begin with a semicolon (any semicolon not in a quoted string or in a comment marks the beginning of a comment), and end at the end of the line. I follow the convention of using three semicolons for ‘major’ comments, and single semicolons for local ones.
When describing the general pattern of an S-expression, we enclose names of syntactic variables in angle brackets. So the notation
(document <pre-DTD> <DTD> <after-DTD>)
means (for example) that a document information item is a list containing the literal keyword document, followed by pre-DTD material, the DTD, and after-DTD material. In actual examples, the syntactic variables pre-DTD, DTD, and after-DTD would be replaced, along with their angle brackets, by appropriate S-expressions.
It is conventional to give predicates (functions which return a Boolean value) names ending in '?' (in Scheme) or 'p' (in Lisp). I'll use the Lisp convention, since it works in both languages.

2. Representation of document instances with and without type information

We use two distinct notations to represent XML documents: the first, described in this section, is adapted from proposals made several years ago by Robert Amsler (in private correspondence) and Erik Naggum (on comp.text.sgml), and represents each element and attribute as an S-expression. In recognition of the fact that Amsler and Naggum were here first, and that I've added some extra information, I call it Augmented Amsler/Naggum Form. The second notation is a representation based on the information items and their properties as defined in the XML Information Set specification; it is described in the following section.
NOTE: it's not clear to the author whether it's worth while to introduce both of these notations. The primary utility of the simpler notation lies in its relative compactness; I currently suspect it might be a more useful S-expression notation for annotation, in schema components. It may also be useful in illustrating the association of types with elements and attributes, without going into all the details. END NOTE.
In the simpler notation, we augment the obvious mapping of XML to S-expressions with an indication of the type of each element. To simplify our representation, we assume that each type may be identified using a pair consisting of a namespace name and a local name. For top-level types, the local name is the name assigned to the type; for anonymous types, it is an arbitrary name guaranteed unique.
The document is represented by a list with four items:
  • the keyword “document
  • a list of items appearing before the document type declaration (here, the empty list); these will be processing instructions and comments
  • a list representing the DTD itself (here, the empty list, and because nothing discussed here relies on information about the DTD, we don't need to get into details about what would be here if the document actually had a DTD)
  • a list representing the items which occurred after the DTD (here, the XML declaration, represented as a processing instruction, and the top-level element of the document); this will always be a list consisting of zero or more processing instructions and comments followed by a single element
(document <pre-DTD> <DTD> <after-DTD>)
Each element is represented by a list with five items:
  • the keyword “element
  • the element's generic identifier
  • the element's datatype (if schema validation did not associate a type with this element, then the type will be the XML Schema anyType)
  • a list of attributes (see below)
  • a list of children; each will be an element, a processing instruction, a comment, or a text node
(element <gi> <datatype> (<attributes>) (<children>))
The type is given as a namespace-localname pair, e.g.
("http://www.w3.org/2001/XMLSchema" . integer)
For compactness in the display, in most examples in this document I use a symbol instead of a string containing the full URI, thus:
(xsd . integer)
Readers concerned about this can imagine, if they will, that the symbol xsd is a variable name, and that this variable has as a value the string "http://www.w3.org/2001/XMLSchema". A top-level assignment like this[2] will do the trick:
(defconst xsd "http://www.w3.org/2001/XMLSchema"
  "The namespace name for the XSD namespace.")
Or, in scheme:
;;; The symbol xsd denotes the namespace name for the XSD namespace.
(define xsd "http://www.w3.org/2001/XMLSchema")
If the type is not bound to a particular namespace, then nil will appear as the first item in the pair. Since nil is not a string containing a legal URI, this causes no ambiguity.
For now I assume that all types have somehow been given identifiers, including anonymous types; if the type has a name, we'll use that, and for anonymous types we'll invent something. Our S-expression representation of datatypes (see below) will associate each type with a unique identifier.
Each attribute is represented by a list with three items:
  • the attribute's name (as a symbol, if the attribute is local to the element; as a namespace-name/local-name pair otherwise)
  • the attribute's datatype (if schema validation did not associate a type with this attribute, then the type will be the XML Schema anySimpleType)
  • the attribute value (for now, always represented as a quoted string — perhaps we should say this is the attribute's lexical form instead).
(element <gi> <datatype> (<attributes>) (<children>))

2.1. Notation for typed values

XML Schema provides a number of atomic types which have no simple or obvious representation as Lisp objects. In the current version of this document, the S-expressions used to represent attributes provide both the lexical form of the attribute, and the name of the datatype associated with the attribute. There is no direct representation of a typed value.
It might be useful to allow typed values to be represented directly using a sort of manifest typing, thus: ((<namespace-name> <local-name>) <value>), where
  • namespace-name gives the name of the namespace in which the type is defined
  • local-name gives the name of the type within that namespace
  • value is a literal representation of the value, using an appropriate native Lisp datatype
Using this convention, a date would be represented here not simply as "2001-05-02" but as (for example) ((xsd . date) "2001-05-02") or ((xsd:date) "2001-05-02"). The latter form would require a special way to bind name prefixes to namespaces.

2.2. The purchase-order example (without XML-Schema validation)

For example, let us consider an expanded version of the sample purchase order po.xml given in the XML Schema Primer (the expansions consist in additional comments and processing instructions, to provide illustrations of those constructs):
<?xml version="1.0"?>
<!--* This is a mildly augmented version of the XML Schema
    * Primer's purchase-order example.
    *-->
<!--* It was created by C. M. Sperberg-McQueen to illustrate the XML infoset.
    * Revisions:
    * 2001-07-30 : CMSMcQ : add some comments and processing instructions,
    *                       to illustrate that bit. 
    *-->
<?demo-pi   This is a demonstration PI at the top level. ?>
<po:purchaseOrder 
    orderDate="1999-10-20" 
    xmlns:="http://www.example.com/PO1"
    xmlns:po="http://www.example.com/PO1">
    <?my-app data for my app ?>
    <po:shipTo country="US">
        <name>Alice Smith</name>
        <po:street>123 Maple Street</po:street>
        <city>Mill Valley</city>
        <po:state>CA</po:state>
        <zip>90952</zip>
    </po:shipTo>
    <po:billTo country="US">
        <name>Robert Smith</name>
        <po:street>8 Oak Avenue</po:street>
        <city>Old Town</city>
        <po:state>PA</po:state>
        <zip>95819</zip>
    </po:billTo>
    <po:comment>Hurry, my lawn is going wild!</po:comment>
    <?my-app more data for my app ?>
    <?other-app data for someone else's app ?>
    <!--* N.B. using processing instructions this way may not be robust *-->
    <po:items>
        <po:item partNum="872-AA">
            <po:productName>Lawnmower</po:productName>
            <po:quantity>1</po:quantity>
            <po:USPrice>148.95</po:USPrice>
            <po:comment>Confirm this is electric</po:comment>
        </po:item>
        <po:item partNum="926-AA">
            <po:productName>Baby Monitor</po:productName>
            <po:quantity>1</po:quantity>
            <po:USPrice>39.98</po:USPrice>
            <po:shipDate>1999-05-21</po:shipDate>
        </po:item>
    </po:items>
</po:purchaseOrder>
In the notation used here, this document would be represented (prior to schema validation, and after removal of element-only whitespace) thus:
;;; S-expressions in Augmented Amsler/Naggum Form 
;;; generated by stylesheet xmlnag.xsl 

(document () () (
  (comment "* This is a mildly augmented version of the XML Schema
    * Primer's purchase-order example.
    *")

  (comment "* It was created by C. M. Sperberg-McQueen to illustrate the XML infoset.
    * Revisions:
    * 2001-07-30 : CMSMcQ : add some comments and processing instructions,
    *                       to illustrate that bit. 
    *")

  (pi demo-pi This is a demonstration PI at the top level. )

  (element po:purchaseOrder
    (xsd . anyType)
    ((orderDate (xsd . anySimpleType) "1999-10-20") )
    (
     (pi my-app data for my app )
     (element po:shipTo
       (xsd . anyType)
       ((country (xsd . anySimpleType) "US") )
       (
	(element name (xsd . anyType) () ("Alice Smith"))
	(element po:street (xsd . anyType) () ("123 Maple Street")) 
	(element city (xsd . anyType) () ("Mill Valley"))
	(element po:state (xsd . anyType) () ("CA")) 
	(element zip (xsd . anyType) () ("90952")) 
	)) ; end po:shipTo
     (element po:billTo
	(xsd . anyType)
	((country (xsd . anySimpleType) "US") )
	(
	 (element name (xsd . anyType) () ("Robert Smith")) 
	 (element po:street (xsd . anyType) () ("8 Oak Avenue")) 
	 (element city (xsd . anyType) () ("Old Town")) 
	 (element po:state (xsd . anyType) () ("PA")) 
	 (element zip (xsd . anyType) () ("95819")) 
	 )) ; end po:billTo

     (element po:comment
	(xsd . anyType)
	()
	("Hurry, my lawn is going wild!")) ; end po:comment
     (pi my-app more data for my app )
     (pi other-app data for someone else's app )
     (comment "* N.B. using processing instructions this way may not be robust *")
     (element po:items
       (xsd . anyType)
       ()
       (
	(element po:item
	  (xsd . anyType)
	  ((partNum (xsd . anySimpleType) "872-AA") )
	  (
	   (element po:productName (xsd . anyType) () ("Lawnmower")) 
	   (element po:quantity (xsd . anyType) () ("1")) 
	   (element po:USPrice (xsd . anyType) () ("148.95")) 
	   (element po:comment (xsd . anyType) () ("Confirm this is electric")) 
	   )) ; end po:item

	(element po:item
	  (xsd . anyType)
	  ((partNum (xsd . anySimpleType) "926-AA") )
	  (
	   (element po:productName (xsd . anyType) () ("Baby Monitor")) 
	   (element po:quantity (xsd . anyType) () ("1")) 
	   (element po:USPrice (xsd . anyType) () ("39.98")) 
	   (element po:shipDate (xsd . anyType) () ("1999-05-21")) 
	   )) ; end po:item
	)) ; end po:items
     )) ; end po:purchaseOrder
  )) ; end document

2.3. The purchase-order example (after XML-Schema validation)

After schema validation using the schema defined in the primer as po1.xsd, some type information would change; let us associate the symbol po with the namespace “http://www.example.com/PO1”.[3]
;;; S-expressions in Augmented Amsler/Naggum Form 
;;; generated by stylesheet xmlnag.xsl 
;;; type information augmented / changed by hand
;;; insignificant whitespace deleted by hand 

(document () () (
  (comment "* This is a mildly augmented version of the XML Schema
    * Primer's purchase-order example.
    *")

  (comment "* It was created by C. M. Sperberg-McQueen to illustrate the XML infoset.
    * Revisions:
    * 2001-07-30 : CMSMcQ : add some comments and processing instructions,
    *                       to illustrate that bit. 
    *")

  (pi demo-pi This is a demonstration PI at the top level. )

  (element (po . purchaseOrder)
    (po . purchaseOrderType)
    ((orderDate (xsd . date) "1999-10-20") )
    (
     (pi my-app data for my app )
     (element (po . shipTo)
       (po . USAddress)
       ((country (xsd . NMTOKEN) "US") )
       (
	(element (po . name) (xsd . string) () ("Alice Smith"))
	(element (po . street) (xsd . string) () ("123 Maple Street")) 
	(element (po . city) (xsd . string) () ("Mill Valley"))
	(element (po . state) (xsd . string) () ("CA")) 
	(element (po . zip) (xsd . decimal) () ("90952")) 
	)) ; end po:shipTo
     (element (po . billTo)
	(po . USAddress)
	((country (xsd . NMTOKEN) "US") )
	(
	 (element (po . name) (xsd . string) () ("Robert Smith")) 
	 (element (po . street) (xsd . string) () ("8 Oak Avenue")) 
	 (element (po . city) (xsd . string) () ("Old Town")) 
	 (element (po . state) (xsd . string) () ("PA")) 
	 (element (po . zip) (xsd . decimal) () ("95819")) 
	 )) ; end po:billTo

     (element (po . comment) (xsd . string) ()
	("Hurry, my lawn is going wild!")) ; end po:comment
     (pi my-app more data for my app )
     (pi other-app data for someone else's app )
     (comment "* N.B. using processing instructions this way may not be robust *")
     (element (po . items) (po . Items) ()
       (
	(element (po . item)
	  (xsd . type-004)
	  ((partNum (po . SKU) "872-AA") )
	  (
	   (element (po . productName) (xsd . string) () ("Lawnmower")) 
	   (element (po . quantity) (xsd . type-005) () ("1")) 
	   (element (po . USPrice) (xsd . decimal) () ("148.95")) 
	   (element (po . comment) (xsd . string) () ("Confirm this is electric")) 
	   )) ; end po:item

	(element (po . item)
	  (xsd . type-004)
	  ((partNum (xsd . SKU) "926-AA") )
	  (
	   (element (po . productName) (xsd . string) () ("Baby Monitor")) 
	   (element (po . quantity) (xsd . type-005) () ("1")) 
	   (element (po . USPrice) (xsd . decimal) () ("39.98")) 
	   (element (po . shipDate) (xsd . string) () ("1999-05-21")) 
	   )) ; end po:item
	)) ; end po:items
     )) ; end po:purchaseOrder
  )) ; end document

3. Representation of components and information sets

In general, we would like to represent each component as an information item, and each information item as a list containing
  • a keyword identifying the kind of item it is (eii for element information item, aii for an attribute information item, etc.)
  • an association list giving the properties of the item; no property will occur more than once in the same association list[4]
There are, however, a few complications.

3.1. Component-valued properties

The value of some properties may be other components or information items, or sets or sequences of such. The XML Information Set specification does not require a particular representation for this kind of relationship; an implementation might use pointers, or physical embedding, or a variety of other methods of conveying the relevant information.
Since our purpose is mostly to exhibit schema structure and validation behavior in a simple and obvious way, we give each information item a unique identifier, and provide the relevant identifier as the value of a property. We will define a utility function which finds information items given their names.
With this modification, the basic representation of any information item is as a list of three items:
  • a type (or kind or sort)
  • a unique identifier
  • an association list of properties
N.B. We won't concern ourselves further in this document with how the unique identifiers are generated, or what they should look like in a production system. XML IDs, XPointer expressions, and various flavors of normalized universal names for schema components are all on the table; our examples will show them as simple tokens which could serve as XML IDs, but that is only because I don't want to spend time here on the details of the problem.
We could, that is, nest children (for example) inside their parent thus:
(eii (
  (namespace-name . "http://www.example.com/P01")
   ...
  (children (
    (pi ...)
    (eii ...)
    (eii ...)
  )
  ...
))
Instead, we pull the children out (so we have a flat set of information items, none nested within any other) and use unique names to refer back and forth:
(eii e-1 (
  (namespace-name . "http://www.example.com/P01")
   ...
  (children (pi-1 e-2 e-3))
  ...
))

(pi pi-1 (... (parent e-1)))
(eii e-2 (... (parent e-1)))
(eii e-3 (... (parent e-1)))

3.2. Absent, unknown, no-valued properties

The XML Infoset spec distinguishes properties which are absent from properties which have a value which is the empty string, the empty list, the empty set, etc. For our purposes, we'd like to exploit standard Lisp routines to work with properties and their values, which means that if we ask for the value of a property for which no value is specified, we will get () or nil back. In cases where the property is present but could have the empty list as its value, this will lead to ambiguity. To eliminate the ambiguity, we will use the identifier empty-list for the case where the empty list really is present as a value.
So, for example, if the notations property of the document information item is not known or not provided for some reason, a conventional Lisp inquiry will return the empty list (or nil, which is a different lexical form for the same Lisp object):
(defconst mydoc '(document d-1 (...)))

(get-property 'notations mydoc) 
==> nil

3.3. Property names

For convenience, we replace blank spaces in property names with hyphens.

3.4. The purchase-order example

In the item-and-property notation used here, the basic information set for the sample purchase order po.xml as given above would look as described in the following paragraphs.
The document information item has the unique identifier document-node:
(document document-node (
 (children . ( comment-1 comment-2 pi-demo-pi-1 elem-1))
 (document-element . elem-1)
 (notations . ())
 (unparsed-entities . ())
 (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
 (standalone . ())
 (version . ())
 (all-declarations-processed . nil)
 )) ; end document
Note that since the standalone and version properties take Boolean and string values respectively, there is no ambiguity in explicitly representing their absence using nil.
The top-level element information item illustrates the properties for elements:
(eii elem-1 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . purchaseOrder)
  (prefix . po) ; omit this?
  (children . ( scii-1 pi-my-app-1 scii-2 elem-2 scii-14 elem-8 
		scii-26 elem-14 scii-28 pi-my-app-2 scii-29 
		pi-other-app-1 scii-30 comment-3 scii-31 elem-15 scii-53))
  (attributes . ( elem-1@orderDate))
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . document-node)))
(This version was generated automatically and I haven't hand-edited the properties which cannot be generated using an XSLT stylesheet.)
The orderDate attribute on the top-level element illustrates properties for attributes:
(aii elem-1@orderDate (
  (namespace-name . ()) 
  (local-name . orderDate)
  (prefix . ()) 
  (normalized-value . "1999-10-20")
  (specified . t)
  (attribute-type . unknown) 
  (references . unknown) 
  (owner-element . elem-1)
  ))
A full S-expression rendition of the document, using the item-property notation, is in an appendix.

4. Attribute declarations

Attribute declaration components are discussed in XML Schema Part 1, section 3.2 Attribute Declarations. They are one of the principal component types.

4.1. Attribute-declaration component structure

Like all components, we expose attribute-declaration components as information items, that is as lists consisting of a keyword, a unique identifier for the information item, and an association list containing the set of property-value pairs associated with this information item. We use the keyword sc-attribute (for ‘schema component: attribute declaration’) to identify components of this kind. The properties of attribute-declaration components are:
  • name
  • target-namespace
  • type-definition
  • scope
  • value-constraint
  • annotation
  (sc-attribute 
    sca-039
    ((name . "lang")
     (target-namespace "http://www.w3.org/1998/xml")
     (type-definition ("http://www.w3.org/2001/XMLSchema" . language))
     (scope . global)
     (value-constraint nil)
     (annotation .
      (element xsd:annotation (xsd . anyType) ()
        ((documentation (xsd . anyType) () 
         ("In due course, we should install the relevant ISO 2- 
         and 3-letter codes as the enumerated possible values . . .")))))))
NOTE: it's not clear what the best way of representing annotations is. We could do them in some literal XML format:
  ("<annotation>
   <documentation>In due course, we should install the relevant ISO 2- 
         and 3-letter codes as the enumerated possible values . . .
   </documentation>
  </annotation>")
or as element and attribute information items. For now, I am using the augmented Amsler/Naggum notation as a compromise between ease of manipulation using Lisp (? but what am I planning to do with these?) and compact representation. END NOTE.

4.2. Validation rules

The validation rule Attribute Locally Valid, which described the validation of an attribute information item against a given attribute declaration, can be defined thus:
< 1 Define aii-locally-valid-p > ≡
(defun aii-locally-valid-p (aii attdecl)
  (let* ((typedef (find-nun (get-property 'type-definition attdecl)))
	 (valcon  (get-property 'valueconstraint attdecl))
	 (keyword (get-property 'keyword valcon))
	 (prelex  (get-property 'value valcon))
	 (normlex (get-property 'normalized-value aii)))
    (and 
     (not (eq attdecl nil))
     (not (eq typedef nil))
     (nv-locally-valid normlex typedef)
     (if (eq keyword 'fixed)
	 (eq (map-to-value normlex typedef) 
	     (map-to-value prelex typedef))))))
This code is used in < File xscomp.el 6 >

In English: first, identify all the bits of information we need:
  • From the attribute declaration passed in as an argument (attdecl), get the associated type definition (typedef) by extracting the type-definition property from attdecl — this will return a name — and then using the find-nun function to locate the component with that name.
  • Identify the value-constraint, if any, in the attribute declaration (valcon),
  • and from it extract the keyword (keyword). The keyword will be either fixed or default, or else it won't be there at all.
  • Also extract the default or fixed value from the value constraint (prelex, for ‘prescribed lexical form’).
  • Get the so-called ‘normalized value’[5] from the attribute information item (normlex, for ‘normalized lexical form’).
Then apply the salient tests:
  • The attribute declaration attdecl must exist (must not be identical to nil).
  • The type definition typedef must exist (be non-nil).
  • The normalized lexical form normlex must be locally valid according to the function nv-locally-valid-p, which is defined elsewhere.
  • Finally, if the value constraint keyword is fixed, then the normalized lexical form and the prescribed lexical form must map to the same value.
This definition uses a number of auxiliary functions defined in section Utility functions:
  • find-attdecl: given an attribute information item, find and return (the name of) the appropriate attribute declaration.
  • find-nun: given the name of a component, return the component itself[6]
  • get-property: given a property name and a component, find and return the value of that property for that component.
  • map-to-value: given a lexical form and a simple type, map the lexical form into the value space of that type and return (an object representing) the value.[7]
The validation rule Schema-validity Assessment (Attribute) can be formalized by the function aii-validity-assessed-p:
< 2 Define aii-validity-assessed-p > ≡
(defun aii-validity-assessed-p (aii)
  (let ((attdecl (find-attdecl aii))
	(typedef (find-nun (get-property 'type-definition attdecl))))
    ;; aii validity has been assessed iff three things are true:
    (and
     ;; 1 we know an attribute declaration for it
     (not (eq attdecl nil))
     ;; 2 we have tested its local validity and gotten a verdict
     ;; of true or false (so we wrap the test in this odd 'if')
     (if (aii-locally-valid aii attdecl)
	 t
       t)
     ;; 3 the test was made with a non-nil attribute declaration 
     ;; (already tested) and non-nil type definition.
     (not (eq typedef nil)))))
This code is used in < File xscomp.el 6 >

This tests several conditions:
  • We can find an attribute declaration for the attribute (see below).
  • We have tested the local validity of the attribute information item. Note that the condition here is not that the attribute be locally valid, but that its validity have been assessed — whether the call to aii-locally-valid-p returns true or false, we count the condition here as having been fulfilled.[8]
  • The local validity was tested with both a non-nil attribute declaration (already tested; the reference to clause 1 of Attribute Locally Valid appears to be redundant) and a non-nil type definition.[9]
To find an attribute declaration given an attribute information item, we must look in two places: either the attribute declaration is found as one of the context-determined declarations (this happens as part of local-validity checking for the attribute's owner element, because it involves attributes declared in the element's complex type), or else it is found among the top-level attribute declarations in the schema, through the validation rule QName resolution (instance). We can represent this formally as:
< 3 Define find-attdecl > ≡
(defun find-attdecl (aii)
  (or (find-context-determined-attdecl aii)
      (find-qname-resolved-attdecl aii)))
This code is used in < File xscomp.el 6 >

These two functions, in turn, are (will eventually be) defined elsewhere.
Finally, this section of the XML Schema spec defines the concept of strict assessment of attribute validity: it is identical with that of local-validity assessment:
< 4 Define aii-validity-strictly-assessed-p > ≡
(defun aii-validity-strictly-assessed-p (aii)
  (aii-validity-assessed-p aii))
This code is not used elsewhere.

4.3. Infoset contributions

To be continued ...
(This section may push me to a less naive and less repetitive definition of the functions in the preceding section. For example, consider the Boolean function for aii-validity-assessed-p. It is odd to say the least, as it causes itself to be true in some cases by attempting to validate the attribute information item. Perhaps what we really need is a function to attempt to calculate the infoset contributions (in the form of an association list, perhaps), and then a redefinition of the other functions in terms of checking the results by inspecting the association list.)

5. Element declarations

Element declaration components are discussed in XML Schema Part 1, section 3.3 Element Declarations. They are one of the principal component types.

6. Complex types

Complex type definition components are discussed in XML Schema Part 1, section 3.4 Complex Type Definitions. They are one of the principal component types.

7. Simple type definitions

Simple type definitions are discussed in XML Schema Part 1, section 3.14 Simple Type Definitions. They are one of the principal component types.

8. Attribute use

Components representing uses (rather than declarations) of attributes are discussed in XML Schema Part 1, section 3.5 AttributeUses. They are a helper component type.

9. Attribute groups

Attribute-group components are discussed in XML Schema Part 1, section 3.6 Attribute Group Definitions. They are one of the secondary component types.

10. Model group definitions

Model group definitions are discussed in XML Schema Part 1, section 3.7 Model Group Definitions. They are one of the secondary component types.

11. Model groups

Model groups are discussed in XML Schema Part 1, section 3.8 Model Groups. They are a helper component type.

12. Content-model particles

Content-model particles are discussed in XML Schema Part 1, section 3.9 Particles. They are a helper component type.

13. Wildcards

Wildcard particles are discussed in XML Schema Part 1, section 3.10 Wildcards. They are a helper component type.

14. Identity constraints

Components for identity constraints are discussed in XML Schema Part 1, section 3.11 Identity-constraint Definitions. They are one of the secondary component types.

15. Notations

Notation declarations are discussed in XML Schema Part 1, section 3.12 Notation Declarations. They are one of the secondary component types.

16. Annotations

Components for user-supplied annotations are discussed in XML Schema Part 1, section 3.13 Annotations. They are a helper component type.

17. Top-level schema components

Top-level schema components are discussed in XML Schema Part 1, section 3.15 Schemas as a Whole.

18. Utility functions

From time to time in this document we have had occasion to use various Lisp functions which are not defined as part of the language. Their definitions are here.

18.1. Extracting properties from information items

To extract a property from an information item, we use the get-property function, which is defined as follows:
< 5 Define get-property > ≡
(defun get-property (propname component)
  (cdr (assq propname (caddr component))))
This code is used in < File xscomp.el 6 >

The expression (caddr component) extracts the association list from the component (it's the car of the cdr of the cdr); the assq function searches it for the property identified by propname. Since assq returns the property-value pair and we want just the value, we take the cdr of what it returns.

18.2. Summary of functions

In order to allow the code fragments provided here to be executed, we gather them all here by reference into one scrap of code, which a special processor will write out into the file xscomp.el in the same directory as this document.
< 6 File xscomp.el > ≡
< Define aii-locally-valid-p 1 >
< Define aii-validity-assessed-p 2 >
< Define find-attdecl 3 >
< Define get-property 5 >
This code is not used elsewhere.


A. References

This list includes a number of useful introductions to Lisp and Scheme, for reference by readers who desire more familiarity with the notation.

Biron, Paul V., and Ashok Malhotra, ed. XML Schema Part 2: Datatypes. W3C Recommendation 2 May 2001. [Cambridge, Mass., Sophia-Antipolis, Tokyo]: W3C, 2001. http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/

Brown, Allen, Matthew Fuchs, Jonathan Robie, and Philip Wadler, ed. XML Schema: Formal Description. W3C Working Draft, 20 March 2001. [Cambridge, Mass., Sophia-Antipolis, Tokyo]: W3C, 2001. http://www.w3.org/TR/2001/WD-xmlschema-formal-20010320/

Chassell, Robert J. Programming in Emacs Lisp: An Introduction. Edition 1.04. Boston: Free Software Foundation, 1995. [Current version online at http://www.gnu.org/manual/emacs-lisp-intro/emacs-lisp-intro.html.]

Fallside, David, ed. XML Schema Part 0: Primer. W3C Recommendation 2 May 2001. [Cambridge, Mass., Sophia-Antipolis, Tokyo]: W3C, 2001. http://www.w3.org/TR/2001/REC-xmlschema-0-20010502/

Friedman, Daniel P., and Matthias Felleisen. The Little LISPer. Cambridge, Mass.: MIT Press, 1987.

Lewis, Bill, Dan LaLiberte, and the GNU Manual Group. The GNU Emacs Lisp Reference Manual. GNU Emacs Version 19.25 for Unix Users; Edition 2.3. Cambridge, Mass.: Free Software Foundation, 1994. 2 volumes, xx + 384, xx + 364 pp. [Current version online at http://www.gnu.org/manual/elisp-manual-20-2.5/elisp.html]

Thompson, Henry S., David Beech, Murray Maloney, and Noah Mendelsohn, ed. XML Schema Part 1: Structures. W3C Recommendation 2 May 2001. [Cambridge, Mass., Sophia-Antipolis, Tokyo]: W3C, 2001. http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/

B. Infoset for Purchase Order document

The full infoset for the expanded purchase order document is given below, in the form generated by an XSLT stylesheet. This origin means that some properties are represented only by stubs.
;;; S-expressions in item-property Form 
;;; generated by stylesheet xmliset.xsl 

(document document-node (
 (children . ( comment-1 comment-2 pi-demo-pi-1 elem-1))
 (document-element . elem-1)
 (notations . ())
 (unparsed-entities . ())
 (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
 (standalone . ())
 (version . ())
 (all-declarations-processed . nil)
 )) ; end document

(comment-ii comment-1 (
 (content "* This is a mildly augmented version of the XML Schema
    * Primer's purchase-order example.
    *")
 (parent . document-node)))

(comment-ii comment-2 (
 (content "* It was created by C. M. Sperberg-McQueen to illustrate the XML infoset.
    * Revisions:
    * 2001-07-30 : CMSMcQ : add some comments and processing instructions,
    *                       to illustrate that bit. 
    *")
 (parent . document-node)))

(pi pi-demo-pi-1 (
  (target . demo-pi)
  (content . "This is a demonstration PI at the top level. ")
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (notation . unknown) ; to be supplied by other means
  (parent . document-node)))

(eii elem-1 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . purchaseOrder)
  (prefix . po) ; omit this?
  (children . ( scii-1 pi-my-app-1 scii-2 elem-2 scii-14 elem-8 
		scii-26 elem-14 scii-28 pi-my-app-2 scii-29 
		pi-other-app-1 scii-30 comment-3 scii-31 elem-15 scii-53))
  (attributes . ( elem-1@orderDate))
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . document-node)))

(aii elem-1@orderDate (
  (namespace-name . "") ; N.B. the value "" may mean the name is unqualified.
  (local-name . orderDate)
  (prefix . ) ; omit this?
  (normalized-value . "1999-10-20")
  (specified . t)
  (attribute-type . unknown) ; to be supplied by other means
  (references . unknown) ; to be supplied by other means
  (owner-element . elem-1)
  )) 

(seq-cii scii-1 (
  (character-codes "
    ")
  (parent . elem-1)))

(pi pi-my-app-1 (
  (target . my-app)
  (content . "data for my app ")
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (notation . unknown) ; to be supplied by other means
  (parent . elem-1)))

(seq-cii scii-2 (
  (character-codes "
    ")
  (parent . elem-1)))

(eii elem-2 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . shipTo)
  (prefix . po) ; omit this?
  (children . (scii-3 elem-3 scii-5 elem-4 scii-7 elem-5 
		      scii-9 elem-6 scii-11 elem-7 scii-13))
  (attributes . ( elem-2@country))
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-1)))

(aii elem-2@country (
  (namespace-name . "") ; N.B. the value "" may mean the name is unqualified.
  (local-name . country)
  (prefix . ) ; omit this?
  (normalized-value . "US")
  (specified . t)
  (attribute-type . unknown) ; to be supplied by other means
  (references . unknown) ; to be supplied by other means
  (owner-element . elem-2)
  )) 

(seq-cii scii-3 (
  (character-codes "
        ")
  (parent . elem-2)))

(eii elem-3 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . name)
  (prefix . ) ; omit this?
  (children . ( scii-4))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-2)))

(seq-cii scii-4 (
  (character-codes "Alice Smith")
  (parent . elem-3)))

(seq-cii scii-5 (
  (character-codes "
        ")
  (parent . elem-2)))

(eii elem-4 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . street)
  (prefix . po) ; omit this?
  (children . ( scii-6))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-2)))

(seq-cii scii-6 (
  (character-codes "123 Maple Street")
  (parent . elem-4)))

(seq-cii scii-7 (
  (character-codes "
        ")
  (parent . elem-2)))

(eii elem-5 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . city)
  (prefix . ) ; omit this?
  (children . ( scii-8))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-2)))

(seq-cii scii-8 (
  (character-codes "Mill Valley")
  (parent . elem-5)))

(seq-cii scii-9 (
  (character-codes "
        ")
  (parent . elem-2)))

(eii elem-6 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . state)
  (prefix . po) ; omit this?
  (children . ( scii-10))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-2)))

(seq-cii scii-10 (
  (character-codes "CA")
  (parent . elem-6)))

(seq-cii scii-11 (
  (character-codes "
        ")
  (parent . elem-2)))

(eii elem-7 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . zip)
  (prefix . ) ; omit this?
  (children . ( scii-12))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-2)))

(seq-cii scii-12 (
  (character-codes "90952")
  (parent . elem-7)))

(seq-cii scii-13 (
  (character-codes "
    ")
  (parent . elem-2)))

(seq-cii scii-14 (
  (character-codes "
    ")
  (parent . elem-1)))

(eii elem-8 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . billTo)
  (prefix . po) ; omit this?
  (children . ( scii-15 elem-9 scii-17 elem-10 scii-19 
		elem-11 scii-21 elem-12 scii-23 elem-13 scii-25))
  (attributes . ( elem-8@country))
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-1)))

(aii elem-8@country (
  (namespace-name . "") ; N.B. the value "" may mean the name is unqualified.
  (local-name . country)
  (prefix . ) ; omit this?
  (normalized-value . "US")
  (specified . t)
  (attribute-type . unknown) ; to be supplied by other means
  (references . unknown) ; to be supplied by other means
  (owner-element . elem-8)
)) 

(seq-cii scii-15 (
  (character-codes "
        ")
  (parent . elem-8)))

(eii elem-9 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . name)
  (prefix . ) ; omit this?
  (children . ( scii-16))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-8)))

(seq-cii scii-16 (
  (character-codes "Robert Smith")
  (parent . elem-9)))

(seq-cii scii-17 (
  (character-codes "
        ")
  (parent . elem-8)))

(eii elem-10 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . street)
  (prefix . po) ; omit this?
  (children . ( scii-18))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-8)))

(seq-cii scii-18 (
  (character-codes "8 Oak Avenue")
  (parent . elem-10)))

(seq-cii scii-19 (
  (character-codes "
        ")
  (parent . elem-8)))

(eii elem-11 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . city)
  (prefix . ) ; omit this?
  (children . ( scii-20))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-8)))

(seq-cii scii-20 (
  (character-codes "Old Town")
  (parent . elem-11)))

(seq-cii scii-21 (
  (character-codes "
        ")
  (parent . elem-8)))

(eii elem-12 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . state)
  (prefix . po) ; omit this?
  (children . ( scii-22))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-8)))

(seq-cii scii-22 (
  (character-codes "PA")
  (parent . elem-12)))

(seq-cii scii-23 (
  (character-codes "
        ")
  (parent . elem-8)))

(eii elem-13 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . zip)
  (prefix . ) ; omit this?
  (children . ( scii-24))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-8)))

(seq-cii scii-24 (
  (character-codes "95819")
  (parent . elem-13)))

(seq-cii scii-25 (
  (character-codes "
    ")
  (parent . elem-8)))

(seq-cii scii-26 (
  (character-codes "
    ")
  (parent . elem-1)))

(eii elem-14 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . comment)
  (prefix . po) ; omit this?
  (children . ( scii-27))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-1)))

(seq-cii scii-27 (
  (character-codes "Hurry, my lawn is going wild!")
  (parent . elem-14)))

(seq-cii scii-28 (
  (character-codes "
    ")
  (parent . elem-1)))

(pi pi-my-app-2 (
(target . my-app)
(content . "more data for my app ")
(base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
(notation . unknown) ; to be supplied by other means
(parent . elem-1)))

(seq-cii scii-29 (
  (character-codes "
    ")
  (parent . elem-1)))

(pi pi-other-app-1 (
(target . other-app)
(content . "data for someone else's app ")
(base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
(notation . unknown) ; to be supplied by other means
(parent . elem-1)))

(seq-cii scii-30 (
  (character-codes "
    ")
  (parent . elem-1)))

(comment-ii comment-3 (
(content "* N.B. using processing instructions this way may not be robust *")
(parent . elem-1)))

(seq-cii scii-31 (
  (character-codes "
    ")
  (parent . elem-1)))

(eii elem-15 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . items)
  (prefix . po) ; omit this?
  (children . ( scii-32 elem-16 scii-42 elem-21 scii-52))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-1)))

(seq-cii scii-32 (
  (character-codes "
        ")
  (parent . elem-15)))

(eii elem-16 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . item)
  (prefix . po) ; omit this?
  (children . ( scii-33 elem-17 scii-35 elem-18 scii-37 elem-19 scii-39 elem-20 scii-41))
  (attributes . ( elem-16@partNum))
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-15)))

(aii elem-16@partNum (
  (namespace-name . "") ; N.B. the value "" may mean the name is unqualified.
  (local-name . partNum)
  (prefix . ) ; omit this?
  (normalized-value . "872-AA")
  (specified . t)
  (attribute-type . unknown) ; to be supplied by other means
  (references . unknown) ; to be supplied by other means
  (owner-element . elem-16)
  )) 

(seq-cii scii-33 (
  (character-codes "
            ")
  (parent . elem-16)))

(eii elem-17 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . productName)
  (prefix . po) ; omit this?
  (children . ( scii-34))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-16)))

(seq-cii scii-34 (
  (character-codes "Lawnmower")
  (parent . elem-17)))

(seq-cii scii-35 (
  (character-codes "
            ")
  (parent . elem-16)))

(eii elem-18 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . quantity)
  (prefix . po) ; omit this?
  (children . ( scii-36))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-16)))

(seq-cii scii-36 (
  (character-codes "1")
  (parent . elem-18)))

(seq-cii scii-37 (
  (character-codes "
            ")
  (parent . elem-16)))

(eii elem-19 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . USPrice)
  (prefix . po) ; omit this?
  (children . ( scii-38))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-16)))

(seq-cii scii-38 (
  (character-codes "148.95")
  (parent . elem-19)))

(seq-cii scii-39 (
  (character-codes "
            ")
  (parent . elem-16)))

(eii elem-20 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . comment)
  (prefix . po) ; omit this?
  (children . ( scii-40))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-16)))

(seq-cii scii-40 (
  (character-codes "Confirm this is electric")
  (parent . elem-20)))

(seq-cii scii-41 (
  (character-codes "
        ")
  (parent . elem-16)))

(seq-cii scii-42 (
  (character-codes "
        ")
  (parent . elem-15)))

(eii elem-21 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . item)
  (prefix . po) ; omit this?
  (children . ( scii-43 elem-22 scii-45 elem-23 scii-47 elem-24 scii-49 elem-25 scii-51))
  (attributes . ( elem-21@partNum))
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-15)))

(aii elem-21@partNum (
  (namespace-name . "") ; N.B. the value "" may mean the name is unqualified.
  (local-name . partNum)
  (prefix . ) ; omit this?
  (normalized-value . "926-AA")
  (specified . t)
  (attribute-type . unknown) ; to be supplied by other means
  (references . unknown) ; to be supplied by other means
  (owner-element . elem-21)
  )) 

(seq-cii scii-43 (
  (character-codes "
            ")
  (parent . elem-21)))

(eii elem-22 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . productName)
  (prefix . po) ; omit this?
  (children . ( scii-44))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-21)))

(seq-cii scii-44 (
  (character-codes "Baby Monitor")
  (parent . elem-22)))

(seq-cii scii-45 (
  (character-codes "
            ")
  (parent . elem-21)))

(eii elem-23 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . quantity)
  (prefix . po) ; omit this?
  (children . ( scii-46))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-21)))

(seq-cii scii-46 (
  (character-codes "1")
  (parent . elem-23)))

(seq-cii scii-47 (
  (character-codes "
            ")
  (parent . elem-21)))

(eii elem-24 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . USPrice)
  (prefix . po) ; omit this?
  (children . ( scii-48))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-21)))

(seq-cii scii-48 (
  (character-codes "39.98")
  (parent . elem-24)))

(seq-cii scii-49 (
  (character-codes "
            ")
  (parent . elem-21)))

(eii elem-25 (
  (namespace-name . "http://www.example.com/PO1")
  (local-name . shipDate)
  (prefix . po) ; omit this?
  (children . ( scii-50))
  (attributes . ())
  (namespace-attributes . ()) ; to be supplied by other means
  (in-scope-namespaces . ()) ; to be supplied by other means
  (base-URI . "file:/d:/home/cmsmcq/2001/schema/potest.xml")
  (parent . elem-21)))

(seq-cii scii-50 (
  (character-codes "1999-05-21")
  (parent . elem-25)))

(seq-cii scii-51 (
  (character-codes "
        ")
  (parent . elem-21)))

(seq-cii scii-52 (
  (character-codes "
    ")
  (parent . elem-15)))

(seq-cii scii-53 (
  (character-codes "
")
  (parent . elem-1)))

C. XSLT stylesheet to generate infoset in item-property S-expressions

The stylesheet which generates the preceding example is available at xmliset.xsl.

Notes

[1] The names have a historical meaning stemming from the implementation of lists on the IBM 704, where these were assembly language acronyms for ‘contents of address register’ and ‘contents of decrement register’; they are a stumbling block to new learners, but are deeply entrenched in Lisp folklore and are not going to go away.
[2] If a direct representation of typed values is introduced, the definition given here would change to the following:
(defconst xsd '((xsd . anyURI) "http://www.w3.org/2001/XMLSchema")
  "The namespace name for the XSD namespace.")
[3] N.B. the type information in this example was provided manually; there may be typos.
[4] Since we are guaranteed that each property occurs only once, we could, if we preferred, use a property list instead of an association list. Association lists are chosen here primarily because they seem more readable. In a real implementation, where speed would count, I would almost certainly intern the name of each item as a symbol, and use property lists rather than association lists; this would also give me a free check that each item really did have a unique name, and that each property really did appear at most once for each item.
[5] The term value in this property name comes from the XML 1.0 spec. In XML-Schema terms, what is denoted here is a lexical form, not a value.
[6] The nun in the title is an abbreviation for normalized universal name. This function is a way of hiding the details of the naming convention from the rest of the system.
[7] The nature of the object returned is not defined or important here. In a practical system, it's crucial for the utility of the post-schema-validation infoset, but for our purposes the only thing that matters is that map-to-value return the same object for two lexical forms if and only if they map to the same value in the value space. I don't have a clue how I'm going to implement this for some simple types, in particular for anySimpleType. Perhaps I should (a) introduce typed-value notation and (b) use equal rather than eq. Or alternatively, replace the map-to-value function with a compare-values function which takes two lexical forms and a typename as arguments; based on the typename, the function could use eq or equal as appropriate.
[8] In other words, we are executing the if solely for the side effect of running the function in the condition. Some readers might find it clearer to replace the if clause with something like
(progn (aii-locally-valid-p aii attdecl) t)
— but I suspect the if is clearer to most.
[9] I find myself compelled to note here that this function definition really and truly serves only to formalize the definition of the validation rule Schema-Validity Assessment (Attribute). This definition is close to the formulation of the spec, even though it entails redundant checking for the existence of the relevant type definition (and the aii-validity-assessed-p function includes a call to aii-locally-valid-p, but throws its value away.