diff options
Diffstat (limited to 'libxml2/test/relaxng/spec_0.xml')
-rw-r--r-- | libxml2/test/relaxng/spec_0.xml | 3589 |
1 files changed, 3589 insertions, 0 deletions
diff --git a/libxml2/test/relaxng/spec_0.xml b/libxml2/test/relaxng/spec_0.xml new file mode 100644 index 0000000..cb8f7be --- /dev/null +++ b/libxml2/test/relaxng/spec_0.xml @@ -0,0 +1,3589 @@ +<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE article [
+<!-- ELEMENT declarations work around MSXML bug. -->
+<!ELEMENT section ANY>
+<!ATTLIST section id ID #IMPLIED>
+<!ELEMENT appendix ANY>
+<!ATTLIST appendix id ID #IMPLIED>
+<!ELEMENT bibliomixed ANY>
+<!ATTLIST bibliomixed id ID #IMPLIED>
+]>
+<article status="Committee Specification" xmlns:p="http://relaxng.org/ns/proofsystem">
+
+<articleinfo>
+<releaseinfo>$Id: spec.xml,v 1.159 2001/12/02 12:12:12 jjc Exp $</releaseinfo>
+<title>RELAX NG Specification</title>
+<authorgroup>
+<editor>
+ <firstname>James</firstname><surname>Clark</surname>
+ <affiliation>
+ <address><email>jjc@jclark.com</email></address>
+ </affiliation>
+</editor>
+<editor>
+ <surname>MURATA</surname><firstname>Makoto</firstname>
+ <affiliation>
+ <address><email>EB2M-MRT@asahi-net.or.jp</email></address>
+ </affiliation>
+</editor>
+</authorgroup>
+<pubdate>3 December 2001</pubdate>
+<releaseinfo role="meta">
+$Id: spec.xml,v 1.159 2001/12/02 12:12:12 jjc Exp $
+</releaseinfo>
+
+<copyright><year>2001</year><holder>OASIS</holder></copyright>
+
+<legalnotice>
+
+<para>Copyright © The Organization for the Advancement of
+Structured Information Standards [OASIS] 2001. All Rights
+Reserved.</para>
+
+<para>This document and translations of it may be copied and furnished
+to others, and derivative works that comment on or otherwise explain
+it or assist in its implementation may be prepared, copied, published
+and distributed, in whole or in part, without restriction of any kind,
+provided that the above copyright notice and this paragraph are
+included on all such copies and derivative works. However, this
+document itself may not be modified in any way, such as by removing
+the copyright notice or references to OASIS, except as needed for the
+purpose of developing OASIS specifications, in which case the
+procedures for copyrights defined in the OASIS Intellectual Property
+Rights document must be followed, or as required to translate it into
+languages other than English.</para>
+
+<para>The limited permissions granted above are perpetual and will not
+be revoked by OASIS or its successors or assigns.</para>
+
+<para>This document and the information contained herein is provided
+on an <quote>AS IS</quote> basis and OASIS DISCLAIMS ALL WARRANTIES,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE
+USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY
+IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+PURPOSE.</para>
+
+</legalnotice>
+
+<legalnotice role="status"><title>Status of this Document</title>
+
+<para>This Committee Specification was approved for publication by the
+OASIS RELAX NG technical committee. It is a stable document which
+represents the consensus of the committee. Comments on this document
+may be sent to <ulink
+url="mailto:relax-ng-comment@lists.oasis-open.org"
+>relax-ng-comment@lists.oasis-open.org</ulink>.</para>
+
+<para>A list of known errors in this document is available at <ulink
+url="http://www.oasis-open.org/committees/relax-ng/spec-20011203-errata.html"
+>http://www.oasis-open.org/committees/relax-ng/spec-20011203-errata.html</ulink
+>.</para>
+
+</legalnotice>
+
+<abstract>
+<para>This is the definitive specification of RELAX NG, a simple
+schema language for XML, based on <xref linkend="relax"/> and <xref
+linkend="trex"/>. A RELAX NG schema specifies a pattern for the
+structure and content of an XML document. A RELAX NG schema is itself
+an XML document.</para>
+</abstract>
+
+<revhistory>
+<revision>
+ <revnumber>Committee Specification</revnumber>
+ <date>3 December 2001</date>
+</revision>
+<revision>
+ <revnumber>Committee Specification</revnumber>
+ <date>11 August 2001</date>
+</revision>
+</revhistory>
+</articleinfo>
+
+
+<section>
+<title>Introduction</title>
+
+<para>This document specifies</para>
+
+<itemizedlist>
+
+<listitem><para>when an XML document is a correct RELAX NG
+schema</para></listitem>
+
+<listitem><para>when an XML document is valid with respect to a
+correct RELAX NG schema</para></listitem>
+
+</itemizedlist>
+
+<para>An XML document that is being validated with respect to a RELAX NG
+schema is referred to as an instance.</para>
+
+<para>The structure of this document is as follows. <xref
+linkend="data-model"/> describes the data model, which is the
+abstraction of an XML document used throughout the rest of the
+document. <xref linkend="full-syntax"/> describes the syntax of a
+RELAX NG schema; any correct RELAX NG schema must conform to this
+syntax. <xref linkend="simplification"/> describes a sequence of
+transformations that are applied to simplify a RELAX NG schema;
+applying the transformations also involves checking certain
+restrictions that must be satisfied by a correct RELAX NG
+schema. <xref linkend="simple-syntax"/> describes the syntax that
+results from applying the transformations; this simple syntax is a
+subset of the full syntax. <xref linkend="semantics"/> describes the
+semantics of a correct RELAX NG schema that uses the simple syntax;
+the semantics specify when an element is valid with respect to a RELAX
+NG schema. <xref linkend="restriction"/> describes restrictions in
+terms of the simple syntax; a correct RELAX NG schema must be such
+that, after transformation into the simple form, it satisfies these
+restrictions. Finally, <xref linkend="conformance"/> describes
+conformance requirements for RELAX NG validators.</para>
+
+<para>A tutorial is available separately (see <xref
+linkend="tutorial"/>).</para>
+
+</section>
+
+<section id="data-model">
+<title>Data model</title>
+
+<para>RELAX NG deals with XML documents representing both schemas and
+instances through an abstract data model. XML documents representing
+schemas and instances must be well-formed in conformance with <xref
+linkend="xml-rec"/> and must conform to the constraints of <xref
+linkend="xml-names"/>.</para>
+
+<para>An XML document is represented by an element. An element consists
+of</para>
+
+<itemizedlist>
+
+<listitem><para>a name</para></listitem>
+
+<listitem><para>a context</para></listitem>
+
+<listitem><para>a set of attributes</para></listitem>
+
+<listitem><para>an ordered sequence of zero or more children; each
+child is either an element or a non-empty string; the sequence never contains
+two consecutive strings</para></listitem>
+
+</itemizedlist>
+
+<para>A name consists of</para>
+
+<itemizedlist>
+<listitem><para>a string representing the namespace URI; the empty
+string has special significance, representing the absence of any
+namespace</para></listitem>
+
+<listitem><para>a string representing the local name; this string matches the NCName
+production of <xref linkend="xml-names"/></para></listitem>
+</itemizedlist>
+
+<para>A context consists of</para>
+
+<itemizedlist>
+<listitem><para>a base URI</para></listitem>
+<listitem><para>a namespace map; this maps prefixes to namespace URIs,
+and also may specify a default namespace URI (as declared
+by the <literal>xmlns</literal> attribute)</para></listitem>
+</itemizedlist>
+
+<para>An attribute consists of</para>
+
+<itemizedlist>
+<listitem><para>a name</para></listitem>
+<listitem><para>a string representing the value</para></listitem>
+</itemizedlist>
+
+<para>A string consists of a sequence of zero or more characters,
+where a character is as defined in <xref linkend="xml-rec"/>.</para>
+
+<para>The element for an XML document is constructed from an instance
+of the <xref linkend="infoset"/> as follows. We use the notation
+[<replaceable>x</replaceable>] to refer to the value of the
+<replaceable>x</replaceable> property of an information item. An
+element is constructed from a document information item by
+constructing an element from the [document element]. An element is
+constructed from an element information item by constructing the name
+from the [namespace name] and [local name], the context from the [base
+URI] and [in-scope namespaces], the attributes from the [attributes],
+and the children from the [children]. The attributes of an element
+are constructed from the unordered set of attribute information items
+by constructing an attribute for each attribute information item. The
+children of an element are constructed from the list of child
+information items first by removing information items other than
+element information items and character information items, and then by
+constructing an element for each element information item in the list
+and a string for each maximal sequence of character information items.
+An attribute is constructed from an attribute information item by
+constructing the name from the [namespace name] and [local name], and
+the value from the [normalized value]. When constructing the name of
+an element or attribute from the [namespace name] and [local name], if
+the [namespace name] property is not present, then the name is
+constructed from an empty string and the [local name]. A string is
+constructed from a sequence of character information items by
+constructing a character from the [character code] of each character
+information item.</para>
+
+<para>It is possible for there to be multiple distinct infosets for a
+single XML document. This is because XML parsers are not required to
+process all DTD declarations or expand all external parsed general
+entities. Amongst these multiple infosets, there is exactly one
+infoset for which [all declarations processed] is true and which does
+not contain any unexpanded entity reference information items. This
+is the infoset that is the basis for defining the RELAX NG data
+model.</para>
+
+<section id="data-model-example">
+<title>Example</title>
+
+<para>Suppose the document
+<literal>http://www.example.com/doc.xml</literal> is as
+follows:</para>
+
+<programlisting><![CDATA[<?xml version="1.0"?>
+<foo><pre1:bar1 xmlns:pre1="http://www.example.com/n1"/><pre2:bar2
+ xmlns:pre2="http://www.example.com/n2"/></foo>
+]]></programlisting>
+
+<para>The element representing this document has</para>
+
+<itemizedlist>
+<listitem><para>a name which has</para>
+<itemizedlist>
+
+<listitem><para>the empty string as the namespace URI, representing
+the absence of any namespace</para></listitem>
+
+<listitem><para><literal>foo</literal> as the local
+name</para></listitem>
+
+</itemizedlist>
+
+</listitem>
+
+<listitem><para>a context which has</para>
+
+<itemizedlist>
+<listitem><para><literal>http://www.example.com/doc.xml</literal> as the base
+URI</para></listitem>
+
+<listitem><para>a namespace map which</para>
+
+<itemizedlist>
+
+<listitem><para>maps the prefix <literal>xml</literal> to the
+namespace URI
+<literal>http://www.w3.org/XML/1998/namespace</literal>
+(the <literal>xml</literal> prefix is implicitly declared
+by every XML document)</para></listitem>
+
+<listitem><para>specifies the empty string as the default namespace
+URI</para></listitem>
+
+</itemizedlist>
+
+</listitem>
+
+</itemizedlist>
+
+</listitem>
+
+<listitem><para>an empty set of attributes</para></listitem>
+
+<listitem><para>a sequence of children consisting
+of an element which has</para>
+
+<itemizedlist>
+<listitem><para>a name which has</para>
+<itemizedlist>
+
+<listitem><para><literal>http://www.example.com/n1</literal> as the
+namespace URI</para></listitem>
+
+<listitem><para><literal>bar1</literal> as the local
+name</para></listitem>
+
+</itemizedlist>
+
+</listitem>
+
+<listitem><para>a context which has</para>
+
+<itemizedlist>
+<listitem><para><literal>http://www.example.com/doc.xml</literal> as the base
+URI</para></listitem>
+
+<listitem><para>a namespace map which</para>
+
+<itemizedlist>
+
+<listitem><para>maps the prefix <literal>pre1</literal> to the
+namespace URI
+<literal>http://www.example.com/n1</literal></para></listitem>
+
+<listitem><para>maps the prefix <literal>xml</literal> to the
+namespace URI
+<literal>http://www.w3.org/XML/1998/namespace</literal></para></listitem>
+
+<listitem><para>specifies the empty string as the default namespace
+URI</para></listitem>
+
+</itemizedlist>
+
+</listitem>
+
+</itemizedlist>
+
+</listitem>
+
+<listitem><para>an empty set of attributes</para></listitem>
+
+<listitem><para>an empty sequence of children</para></listitem>
+
+</itemizedlist>
+
+<para>followed by an element which has</para>
+
+<itemizedlist>
+<listitem><para>a name which has</para>
+<itemizedlist>
+
+<listitem><para><literal>http://www.example.com/n2</literal> as the
+namespace URI</para></listitem>
+
+<listitem><para><literal>bar2</literal> as the local
+name</para></listitem>
+
+</itemizedlist>
+
+</listitem>
+
+<listitem><para>a context which has</para>
+
+<itemizedlist>
+<listitem><para><literal>http://www.example.com/doc.xml</literal> as the base
+URI</para></listitem>
+
+<listitem><para>a namespace map which</para>
+
+<itemizedlist>
+
+<listitem><para>maps the prefix <literal>pre2</literal> to the
+namespace URI
+<literal>http://www.example.com/n2</literal></para></listitem>
+
+<listitem><para>maps the prefix <literal>xml</literal> to the
+namespace URI
+<literal>http://www.w3.org/XML/1998/namespace</literal></para></listitem>
+
+<listitem><para>specifies the empty string as the default namespace
+URI</para></listitem>
+
+</itemizedlist>
+
+</listitem>
+
+</itemizedlist>
+
+</listitem>
+
+<listitem><para>an empty set of attributes</para></listitem>
+
+<listitem><para>an empty sequence of children</para></listitem>
+
+</itemizedlist>
+
+</listitem>
+</itemizedlist>
+
+</section>
+
+</section>
+
+<section id="full-syntax">
+<title>Full syntax</title>
+
+<para>The following grammar summarizes the syntax of RELAX NG.
+Although we use a notation based on the XML representation of an RELAX
+NG schema as a sequence of characters, the grammar must be understood
+as operating at the data model level. For example, although the
+syntax uses <literal><![CDATA[<text/>]]></literal>, an instance or
+schema can use <literal><![CDATA[<text></text>]]></literal> instead,
+because they both represent the same element at the data model level.
+All elements shown in the grammar are qualified with the namespace
+URI:</para>
+
+<programlisting>http://relaxng.org/ns/structure/1.0</programlisting>
+
+<para>The symbols QName and NCName are defined in <xref
+linkend="xml-names"/>. The anyURI symbol has the same meaning as the
+anyURI datatype of <xref linkend="xmlschema-2"/>: it indicates a
+string that, after escaping of disallowed values as described in
+Section 5.4 of <xref linkend="xlink"/>, is a URI reference as defined
+in <xref linkend="rfc2396"/> (as modified by <xref
+linkend="rfc2732"/>). The symbol string matches any string.</para>
+
+<para>In addition to the attributes shown explicitly, any element can
+have an <literal>ns</literal> attribute and any element can have a
+<literal>datatypeLibrary</literal> attribute. The
+<literal>ns</literal> attribute can have any value. The value of the
+<literal>datatypeLibrary</literal> attribute must match the anyURI
+symbol as described in the previous paragraph; in addition, it must
+not use the relative form of URI reference and must not have a
+fragment identifier; as an exception to this, the value may be the
+empty string.</para>
+
+<para>Any element can also have foreign attributes in addition to the
+attributes shown in the grammar. A foreign attribute is an attribute
+with a name whose namespace URI is neither the empty string nor the
+RELAX NG namespace URI. Any element that cannot have string children
+(that is, any element other than <literal>value</literal>, <literal>param</literal>
+and <literal>name</literal>) may have foreign child elements in addition
+to the child elements shown in the grammar. A foreign element is an
+element with a name whose namespace URI is not the RELAX NG namespace
+URI. There are no constraints on the relative position of foreign
+child elements with respect to other child elements.</para>
+
+<para>Any element can also have as children strings that consist
+entirely of whitespace characters, where a whitespace character is one
+of #x20, #x9, #xD or #xA. There are no constraints on the relative
+position of whitespace string children with respect to child
+elements.</para>
+
+<para>Leading and trailing whitespace is allowed for value of each
+<literal>name</literal>, <literal>type</literal> and
+<literal>combine</literal> attribute and for the content of each
+<literal>name</literal> element.</para>
+
+<grammarref src="full.rng"/>
+
+<section id="full-syntax-example">
+<title>Example</title>
+
+<para>Here is an example of a schema in the full syntax for the
+document in <xref linkend="data-model-example"/>.</para>
+
+<programlisting><![CDATA[<?xml version="1.0"?>
+<element name="foo"
+ xmlns="http://relaxng.org/ns/structure/1.0"
+ xmlns:a="http://relaxng.org/ns/annotation/1.0"
+ xmlns:ex1="http://www.example.com/n1"
+ xmlns:ex2="http://www.example.com/n2">
+ <a:documentation>A foo element.</a:document>
+ <element name="ex1:bar1">
+ <empty/>
+ </element>
+ <element name="ex2:bar2">
+ <empty/>
+ </element>
+</element>]]></programlisting>
+
+</section>
+
+</section>
+
+<section id="simplification">
+<title>Simplification</title>
+
+<para>The full syntax given in the previous section is transformed
+into a simpler syntax by applying the following transformation rules
+in order. The effect must be as if each rule was applied to all
+elements in the schema before the next rule is applied. A
+transformation rule may also specify constraints that must be
+satisfied by a correct schema. The transformation rules are applied
+at the data model level. Before the transformations are applied, the
+schema is parsed into an instance of the data model.</para>
+
+<section>
+<title>Annotations</title>
+
+<para>Foreign attributes and elements are removed.</para>
+
+<note><para>It is safe to remove <literal>xml:base</literal>
+attributes at this stage because <literal>xml:base</literal>
+attributes are used in determining the [base URI] of an element
+information item, which is in turn used to construct the base URI of
+the context of an element. Thus, after a document has been parsed
+into an instance of the data model, <literal>xml:base</literal>
+attributes can be discarded.</para></note>
+
+</section>
+
+<section>
+<title>Whitespace</title>
+
+<para>For each element other than <literal>value</literal> and
+<literal>param</literal>, each child that is a string containing only
+whitespace characters is removed.</para>
+
+<para>Leading and trailing whitespace characters are removed from the
+value of each <literal>name</literal>, <literal>type</literal> and
+<literal>combine</literal> attribute and from the content of each
+<literal>name</literal> element.</para>
+
+</section>
+
+<section>
+<title><literal>datatypeLibrary</literal> attribute</title>
+
+<para>The value of each <literal>datatypeLibary</literal> attribute is
+transformed by escaping disallowed characters as specified in Section
+5.4 of <xref linkend="xlink"/>.</para>
+
+<para>For any <literal>data</literal> or <literal>value</literal>
+element that does not have a <literal>datatypeLibrary</literal>
+attribute, a <literal>datatypeLibrary</literal> attribute is
+added. The value of the added <literal>datatypeLibrary</literal>
+attribute is the value of the <literal>datatypeLibrary</literal>
+attribute of the nearest ancestor element that has a
+<literal>datatypeLibrary</literal> attribute, or the empty string if
+there is no such ancestor. Then, any <literal>datatypeLibrary</literal>
+attribute that is on an element other than <literal>data</literal> or
+<literal>value</literal> is removed.</para>
+
+</section>
+
+<section>
+<title><literal>type</literal> attribute of <literal>value</literal> element</title>
+
+<para>For any <literal>value</literal> element that does not have a
+<literal>type</literal> attribute, a <literal>type</literal> attribute
+is added with value <literal>token</literal> and the value of the
+<literal>datatypeLibrary</literal> attribute is changed to the empty
+string.</para>
+
+</section>
+
+<section id="href">
+<title><literal>href</literal> attribute</title>
+
+<para>The value of the <literal>href</literal> attribute on an
+<literal>externalRef</literal> or <literal>include</literal> element
+is first transformed by escaping disallowed characters as specified in
+Section 5.4 of <xref linkend="xlink"/>. The URI reference is then
+resolved into an absolute form as described in section 5.2 of <xref
+linkend="rfc2396"/> using the base URI from the context of the element
+that bears the <literal>href</literal> attribute.</para>
+
+<para>The value of the <literal>href</literal> attribute will be used
+to construct an element (as specified in <xref
+linkend="data-model"/>). This must be done as follows. The URI
+reference consists of the URI itself and an optional fragment
+identifier. The resource identified by the URI is retrieved. The
+result is a MIME entity: a sequence of bytes labeled with a MIME
+media type. The media type determines how an element is constructed
+from the MIME entity and optional fragment identifier. When the media
+type is <literal>application/xml</literal> or
+<literal>text/xml</literal>, the MIME entity must be parsed as an XML
+document in accordance with the applicable RFC (at the term of writing
+<xref linkend="rfc3023"/>) and an element constructed from the result
+of the parse as specified in <xref linkend="data-model"/>. In
+particular, the <literal>charset</literal> parameter must be handled
+as specified by the RFC. This specification does not define the
+handling of media types other than <literal>application/xml</literal>
+and <literal>text/xml</literal>. The <literal>href</literal> attribute
+must not include a fragment identifier unless the registration of the
+media type of the resource identified by the attribute defines the
+interpretation of fragment identifiers for that media type.</para>
+
+<note><para><xref linkend="rfc3023"/> does not define the
+interpretation of fragment identifiers for
+<literal>application/xml</literal> or
+<literal>text/xml</literal>.</para></note>
+
+</section>
+
+<section>
+<title><literal>externalRef</literal> element</title>
+
+<para>An <literal>externalRef</literal> element is transformed as
+follows. An element is constructed using the URI reference that is
+the value of <literal>href</literal> attribute as specified in <xref
+linkend="href"/>. This element must match the syntax for pattern. The
+element is transformed by recursively applying the rules from this
+subsection and from previous subsections of this section. This must
+not result in a loop. In other words, the transformation of the
+referenced element must not require the dereferencing of an
+<literal>externalRef</literal> attribute with an
+<literal>href</literal> attribute with the same value.</para>
+
+<para>Any <literal>ns</literal> attribute on the
+<literal>externalRef</literal> element is transferred to the
+referenced element if the referenced element does not already have an
+<literal>ns</literal> attribute. The <literal>externalRef</literal>
+element is then replaced by the referenced element.</para>
+
+</section>
+
+<section>
+<title><literal>include</literal> element</title>
+
+<para>An <literal>include</literal> element is transformed as follows.
+An element is constructed using the URI reference that is the value of
+<literal>href</literal> attribute as specified in <xref
+linkend="href"/>. This element must be a <literal>grammar</literal>
+element, matching the syntax for grammar.</para>
+
+<para>This <literal>grammar</literal> element is transformed by
+recursively applying the rules from this subsection and from previous
+subsections of this section. This must not result in a loop. In other
+words, the transformation of the <literal>grammar</literal> element
+must not require the dereferencing of an <literal>include</literal>
+attribute with an <literal>href</literal> attribute with the same
+value.</para>
+
+<para>Define the <firstterm>components</firstterm> of an element to
+be the children of the element together with the components of any
+<literal>div</literal> child elements. If the
+<literal>include</literal> element has a <literal>start</literal>
+component, then the <literal>grammar</literal> element must have a
+<literal>start</literal> component. If the <literal>include</literal>
+element has a <literal>start</literal> component, then all
+<literal>start</literal> components are removed from the
+<literal>grammar</literal> element. If the <literal>include</literal>
+element has a <literal>define</literal> component, then the
+<literal>grammar</literal> element must have a
+<literal>define</literal> component with the same name. For every
+<literal>define</literal> component of the <literal>include</literal>
+element, all <literal>define</literal> components with the same name
+are removed from the <literal>grammar</literal> element.</para>
+
+<para>The <literal>include</literal> element is transformed into a
+<literal>div</literal> element. The attributes of the
+<literal>div</literal> element are the attributes of the
+<literal>include</literal> element other than the
+<literal>href</literal> attribute. The children of the
+<literal>div</literal> element are the <literal>grammar</literal>
+element (after the removal of the <literal>start</literal> and
+<literal>define</literal> components described by the preceding
+paragraph) followed by the children of the <literal>include</literal>
+element. The <literal>grammar</literal> element is then renamed to
+<literal>div</literal>.</para>
+
+</section>
+
+<section>
+<title><literal>name</literal> attribute of <literal>element</literal>
+and <literal>attribute</literal> elements</title>
+
+<para>The <literal>name</literal> attribute on an
+<literal>element</literal> or <literal>attribute</literal> element is
+transformed into a <literal>name</literal> child element.</para>
+
+<para>If an <literal>attribute</literal> element has a
+<literal>name</literal> attribute but no <literal>ns</literal>
+attribute, then an <literal>ns=""</literal> attribute is added to the
+<literal>name</literal> child element.</para>
+
+</section>
+
+<section>
+<title><literal>ns</literal> attribute</title>
+
+<para>For any <literal>name</literal>, <literal>nsName</literal> or
+<literal>value</literal> element that does not have an
+<literal>ns</literal> attribute, an <literal>ns</literal> attribute is
+added. The value of the added <literal>ns</literal> attribute is the
+value of the <literal>ns</literal> attribute of the nearest ancestor
+element that has an <literal>ns</literal> attribute, or the empty
+string if there is no such ancestor. Then, any <literal>ns</literal>
+attribute that is on an element other than <literal>name</literal>,
+<literal>nsName</literal> or <literal>value</literal> is
+removed.</para>
+
+<note><para>The value of the <literal>ns</literal> attribute is
+<emphasis role="strong">not</emphasis> transformed either by escaping
+disallowed characters, or in any other way, because the value of the
+<literal>ns</literal> attribute is compared against namespace URIs in
+the instance, which are not subject to any
+transformation.</para></note>
+
+<note><para>Since <literal>include</literal> and
+<literal>externalRef</literal> elements are resolved after
+<literal>datatypeLibrary</literal> attributes are added but before
+<literal>ns</literal> attributes are added, <literal>ns</literal>
+attributes are inherited into external schemas but
+<literal>datatypeLibrary</literal> attributes are not.</para></note>
+
+</section>
+
+<section>
+<title>QNames</title>
+
+<para>For any <literal>name</literal> element containing a prefix, the
+prefix is removed and an <literal>ns</literal> attribute is added
+replacing any existing <literal>ns</literal> attribute. The value of
+the added <literal>ns</literal> attribute is the value to which the
+namespace map of the context of the <literal>name</literal> element
+maps the prefix. The context must have a mapping for the
+prefix.</para>
+
+</section>
+
+<section>
+<title><literal>div</literal> element</title>
+
+<para>Each <literal>div</literal> element is replaced by its
+children.</para>
+
+</section>
+
+<section id="number-child-elements">
+<title>Number of child elements</title>
+
+<para>A <literal>define</literal>, <literal>oneOrMore</literal>,
+<literal>zeroOrMore</literal>, <literal>optional</literal>, <literal>list</literal> or
+<literal>mixed</literal> element is transformed so that it has exactly
+one child element. If it has more than one child element, then its
+child elements are wrapped in a <literal>group</literal>
+element. Similarly, an <literal>element</literal> element is transformed so
+that it has exactly two child elements, the first being a name class
+and the second being a pattern. If it has more than two child elements,
+then the child elements other than the first are wrapped in a
+<literal>group</literal> element.</para>
+
+<para>A <literal>except</literal> element is transformed
+so that it has exactly one child element. If it has more
+than one child element, then its child elements are wrapped
+in a <literal>choice</literal> element.</para>
+
+<para>If an <literal>attribute</literal> element has only one child
+element (a name class), then a <literal>text</literal> element is
+added.</para>
+
+<para>A <literal>choice</literal>, <literal>group</literal> or
+<literal>interleave</literal> element is transformed so that it has
+exactly two child elements. If it has one child element, then it is
+replaced by its child element. If it has more than two child
+elements, then the first two child elements are combined into a new
+element with the same name as the parent element and with the first
+two child elements as its children. For example,</para>
+
+<programlisting><choice> <replaceable>p1</replaceable> <replaceable>p2</replaceable> <replaceable>p3</replaceable> </choice></programlisting>
+
+<para>is transformed to</para>
+
+<programlisting><choice> <choice> <replaceable>p1</replaceable> <replaceable>p2</replaceable> </choice> <replaceable>p3</replaceable> </choice></programlisting>
+
+<para>This reduces the number of child elements by one. The
+transformation is applied repeatedly until there are exactly two child
+elements.</para>
+
+</section>
+
+<section>
+<title><literal>mixed</literal> element</title>
+
+<para>A <literal>mixed</literal> element is transformed into an
+interleaving with a <literal>text</literal> element:</para>
+
+<programlisting><mixed> <replaceable>p</replaceable> </mixed></programlisting>
+
+<para>is transformed into</para>
+
+<programlisting><interleave> <replaceable>p</replaceable> <text/> </interleave></programlisting>
+
+</section>
+
+<section>
+<title><literal>optional</literal> element</title>
+
+<para>An <literal>optional</literal> element is transformed into
+a choice with <literal>empty</literal>:</para>
+
+<programlisting><optional> <replaceable>p</replaceable> </optional></programlisting>
+
+<para>is transformed into</para>
+
+<programlisting><choice> <replaceable>p</replaceable> <empty/> </choice></programlisting>
+
+</section>
+
+<section>
+<title><literal>zeroOrMore</literal> element</title>
+
+<para>A <literal>zeroOrMore</literal> element is transformed into a choice
+between <literal>oneOrMore</literal> and
+<literal>empty</literal>:</para>
+
+<programlisting><zeroOrMore> <replaceable>p</replaceable> </zeroOrMore></programlisting>
+
+<para>is transformed into</para>
+
+<programlisting><choice> <oneOrMore> <replaceable>p</replaceable> </oneOrMore> <empty/> </choice></programlisting>
+
+</section>
+
+<section id="constraints">
+<title>Constraints</title>
+
+<para>In this rule, no transformation is performed, but various
+constraints are checked.</para>
+
+<note><para>The constraints in this section, unlike the constraints
+specified in <xref linkend="restriction"/>, can be checked without
+resolving any <literal>ref</literal> elements, and are accordingly
+applied even to patterns that will disappear during later stages of
+simplification because they are not reachable (see <xref
+linkend="define-ref"/>) or because of <literal>notAllowed</literal>
+(see <xref linkend="notAllowed"/>).</para></note>
+
+<para>An <literal>except</literal> element that is a child of an
+<literal>anyName</literal> element must not have any
+<literal>anyName</literal> descendant elements. An
+<literal>except</literal> element that is a child of an
+<literal>nsName</literal> element must not have any
+<literal>nsName</literal> or <literal>anyName</literal> descendant
+elements.</para>
+
+<para>A <literal>name</literal> element that occurs as the first child
+of an <literal>attribute</literal> element or as the descendant of the
+first child of an <literal>attribute</literal> element and that has an
+<literal>ns</literal> attribute with value equal to the empty string
+must not have content equal to <literal>xmlns</literal>.</para>
+
+<para>A <literal>name</literal> or <literal>nsName</literal> element
+that occurs as the first child of an <literal>attribute</literal>
+element or as the descendant of the first child of an
+<literal>attribute</literal> element must not have an
+<literal>ns</literal> attribute with value
+<literal>http://www.w3.org/2000/xmlns</literal>.</para>
+
+<note><para>The <xref linkend="infoset"/> defines the namespace URI of
+namespace declaration attributes to be
+<literal>http://www.w3.org/2000/xmlns</literal>.</para></note>
+
+<para>A <literal>data</literal> or <literal>value</literal> element
+must be correct in its use of datatypes. Specifically, the
+<literal>type</literal> attribute must identify a datatype within the
+datatype library identified by the value of the
+<literal>datatypeLibrary</literal> attribute. For a
+<literal>data</literal> element, the parameter list must be one that
+is allowed by the datatype (see <xref
+linkend="data-pattern"/>).</para>
+
+</section>
+
+<section>
+<title><literal>combine</literal> attribute</title>
+
+<para>For each <literal>grammar</literal> element, all
+<literal>define</literal> elements with the same name are combined
+together. For any name, there must not be more than one
+<literal>define</literal> element with that name that does not have a
+<literal>combine</literal> attribute. For any name, if there is a
+<literal>define</literal> element with that name that has a
+<literal>combine</literal> attribute with the value
+<literal>choice</literal>, then there must not also be a
+<literal>define</literal> element with that name that has a
+<literal>combine</literal> attribute with the value
+<literal>interleave</literal>. Thus, for any name, if there is more
+than one <literal>define</literal> element with that name, then there
+is a unique value for the <literal>combine</literal> attribute for
+that name. After determining this unique value, the
+<literal>combine</literal> attributes are removed. A pair of
+definitions</para>
+
+<programlisting><define name="<replaceable>n</replaceable>">
+ <replaceable>p1</replaceable>
+</define>
+<define name="<replaceable>n</replaceable>">
+ <replaceable>p2</replaceable>
+</define></programlisting>
+
+<para>is combined into</para>
+
+<programlisting><define name="<replaceable>n</replaceable>">
+ <<replaceable>c</replaceable>>
+ <replaceable>p1</replaceable>
+ <replaceable>p2</replaceable>
+ </<replaceable>c</replaceable>>
+</define></programlisting>
+
+<para>where <replaceable>c</replaceable> is the value of the
+<literal>combine</literal> attribute. Pairs of definitions are
+combined until there is exactly one <literal>define</literal> element
+for each name.</para>
+
+<para>Similarly, for each <literal>grammar</literal> element all
+<literal>start</literal> elements are combined together. There must
+not be more than one <literal>start</literal> element that does not
+have a <literal>combine</literal> attribute. If there is a
+<literal>start</literal> element that has a <literal>combine</literal>
+attribute with the value <literal>choice</literal>, there must not
+also be a <literal>start</literal> element that has a
+<literal>combine</literal> attribute with the value
+<literal>interleave</literal>.</para>
+
+</section>
+
+<section>
+<title><literal>grammar</literal> element</title>
+
+<para>In this rule, the schema is transformed so that its top-level
+element is <literal>grammar</literal> and so that it has no other
+<literal>grammar</literal> elements.</para>
+
+<para>Define the <firstterm>in-scope grammar</firstterm> for an
+element to be the nearest ancestor <literal>grammar</literal> element. A
+<literal>ref</literal> element <firstterm>refers to</firstterm> a
+<literal>define</literal> element if the value of their
+<literal>name</literal> attributes is the same and their in-scope
+grammars are the same. A <literal>parentRef</literal> element
+<firstterm>refers to</firstterm> a <literal>define</literal> element
+if the value of their <literal>name</literal> attributes is the same
+and the in-scope grammar of the in-scope grammar of the
+<literal>parentRef</literal> element is the same as the in-scope
+grammar of the <literal>define</literal> element. Every
+<literal>ref</literal> or <literal>parentRef</literal> element must
+refer to a <literal>define</literal> element. A
+<literal>grammar</literal> must have a <literal>start</literal> child
+element.</para>
+
+<para>First, transform the top-level pattern
+<replaceable>p</replaceable> into
+<literal><grammar><start><replaceable>p</replaceable></start></grammar></literal>.
+Next, rename <literal>define</literal> elements so that no two
+<literal>define</literal> elements anywhere in the schema have the
+same name. To rename a <literal>define</literal> element, change the
+value of its <literal>name</literal> attribute and change the value of
+the <literal>name</literal> attribute of all <literal>ref</literal>
+and <literal>parentRef</literal> elements that refer to that
+<literal>define</literal> element. Next, move all
+<literal>define</literal> elements to be children of the top-level
+<literal>grammar</literal> element, replace each nested
+<literal>grammar</literal> element by the child of its
+<literal>start</literal> element and rename each
+<literal>parentRef</literal> element to <literal>ref</literal>.</para>
+
+</section>
+
+
+<section id="define-ref">
+<title><literal>define</literal> and <literal>ref</literal> elements</title>
+
+<para>In this rule, the grammar is transformed so that every
+<literal>element</literal> element is the child of a
+<literal>define</literal> element, and the child of every
+<literal>define</literal> element is an <literal>element</literal>
+element.</para>
+
+<para>First, remove any <literal>define</literal> element that is not
+<firstterm>reachable</firstterm>. A <literal>define</literal> element
+is reachable if there is reachable <literal>ref</literal> element
+referring to it. A <literal>ref</literal> element is reachable if it
+is the descendant of the <literal>start</literal> element or of a
+reachable <literal>define</literal> element. Now, for
+each <literal>element</literal> element that is not the child of a
+<literal>define</literal> element, add a <literal>define</literal>
+element to the <literal>grammar</literal> element, and replace the
+<literal>element</literal> element by a <literal>ref</literal> element
+referring to the added <literal>define</literal> element. The value of
+the <literal>name</literal> attribute of the added
+<literal>define</literal> element must be different from value of the
+<literal>name</literal> attribute of all other
+<literal>define</literal> elements. The child of the added
+<literal>define</literal> element is the <literal>element</literal>
+element.</para>
+
+<para>Define a <literal>ref</literal> element to be
+<firstterm>expandable</firstterm> if it refers to a
+<literal>define</literal> element whose child is not an
+<literal>element</literal> element. For each <literal>ref</literal>
+element that is expandable and is a descendant of a
+<literal>start</literal> element or an <literal>element</literal>
+element, expand it by replacing the <literal>ref</literal> element by
+the child of the <literal>define</literal> element to which it refers and
+then recursively expanding any expandable <literal>ref</literal>
+elements in this replacement. This must not result in a loop.
+In other words expanding the replacement of a
+<literal>ref</literal> element having a <literal>name</literal> with
+value <replaceable>n</replaceable> must not require the expansion of
+<literal>ref</literal> element also having a <literal>name</literal>
+with value <replaceable>n</replaceable>. Finally, remove any
+<literal>define</literal> element whose child is not an
+<literal>element</literal> element.</para>
+
+</section>
+
+<section id="notAllowed">
+<title><literal>notAllowed</literal> element</title>
+
+<para>In this rule, the grammar is transformed so that a
+<literal>notAllowed</literal> element occurs only as the child of
+a <literal>start</literal> or <literal>element</literal> element. An
+<literal>attribute</literal>, <literal>list</literal>,
+<literal>group</literal>, <literal>interleave</literal>,
+or <literal>oneOrMore</literal> element that has a
+<literal>notAllowed</literal> child element is transformed into a
+<literal>notAllowed</literal> element. A <literal>choice</literal>
+element that has two <literal>notAllowed</literal> child elements is
+transformed into a <literal>notAllowed</literal> element. A
+<literal>choice</literal> element that has one
+<literal>notAllowed</literal> child element is transformed into its
+other child element. An <literal>except</literal> element that has a
+<literal>notAllowed</literal> child element is removed.
+The preceding transformations are applied
+repeatedly until none of them is applicable any more.
+Any <literal>define</literal> element that is no longer reachable
+is removed.</para>
+
+</section>
+
+<section>
+<title><literal>empty</literal> element</title>
+
+<para>In this rule, the grammar is transformed so that an
+<literal>empty</literal> element does not occur as a child of a
+<literal>group</literal>, <literal>interleave</literal>, or
+<literal>oneOrMore</literal> element or as the second child of
+a <literal>choice</literal> element. A <literal>group</literal>,
+<literal>interleave</literal> or <literal>choice</literal> element
+that has two <literal>empty</literal> child elements is transformed
+into an <literal>empty</literal> element. A <literal>group</literal>
+or <literal>interleave</literal> element that has one
+<literal>empty</literal> child element is transformed into its other
+child element. A <literal>choice</literal> element whose
+second child element is an <literal>empty</literal> element is
+transformed by interchanging its two child elements. A
+<literal>oneOrMore</literal> element that has an
+<literal>empty</literal> child element is transformed into an
+<literal>empty</literal> element. The preceding transformations are applied
+repeatedly until none of them is applicable any more.</para>
+
+</section>
+
+</section>
+
+<section id="simple-syntax">
+<title>Simple syntax</title>
+
+<para>After applying all the rules in <xref
+linkend="simplification"/>, the schema will match the following
+grammar:</para>
+
+<grammarref src="simple.rng"/>
+
+<para>With this grammar, no elements or attributes are allowed other
+than those explicitly shown.</para>
+
+<section id="simple-syntax-example">
+<title>Example</title>
+
+<para>The following is an example of how the schema in <xref
+linkend="full-syntax-example"/> can be transformed into the simple
+syntax:</para>
+
+<programlisting><![CDATA[<?xml version="1.0"?>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <ref name="foo.element"/>
+ </start>
+
+ <define name="foo.element">
+ <element>
+ <name ns="">foo</name>
+ <group>
+ <ref name="bar1.element"/>
+ <ref name="bar2.element"/>
+ </group>
+ </element>
+ </define>
+
+ <define name="bar1.element">
+ <element>
+ <name ns="http://www.example.com/n1">bar1</name>
+ <empty/>
+ </element>
+ </define>
+
+ <define name="bar2.element">
+ <element>
+ <name ns="http://www.example.com/n2">bar2</name>
+ <empty/>
+ </element>
+ </define>
+</grammar>]]></programlisting>
+
+<note><para>Strictly speaking, the result of simplification is an
+instance of the data model rather than an XML document. For
+convenience, we use an XML document to represent an instance of the
+data model.</para></note>
+
+</section>
+
+</section>
+
+<section id="semantics">
+<title>Semantics</title>
+
+<para>In this section, we define the semantics of a correct RELAX NG
+schema that has been transformed into the simple syntax. The
+semantics of a RELAX NG schema consist of a specification of what XML
+documents are valid with respect to that schema. The semantics are
+described formally. The formalism uses axioms and inference rules.
+Axioms are propositions that are provable unconditionally. An
+inference rule consists of one or more antecedents and exactly one
+consequent. An antecedent is either positive or negative. If all the
+positive antecedents of an inference rule are provable and none of the
+negative antecedents are provable, then the consequent of the
+inference rule is provable. An XML document is valid with respect to a
+RELAX NG schema if and only if the proposition that it is valid is
+provable in the formalism specified in this section.</para>
+
+<note><para>This kind of formalism is similar to a proof system.
+However, a traditional proof system only has positive
+antecedents.</para></note>
+
+<para>The notation for inference rules separates the antecedents from
+the consequent by a horizontal line: the antecedents are above the
+line; the consequent is below the line. If an antecedent is of the
+form not(<replaceable>p</replaceable>), then it is a negative
+antecedent; otherwise, it is a positive antecedent. Both axioms and
+inferences
+rules may use variables. A variable has a name and optionally a
+subscript. The name of a variable is italicized. Each variable has a
+range that is determined by its name. Axioms and inference rules are
+implicitly universally quantified over the variables they contain. We
+explain this further below.</para>
+
+<para>The possibility that an inference rule or axiom may contain more
+than one occurrence of a particular variable requires that an identity
+relation be defined on each kind of object over which a variable can
+range. The identity relation for all kinds of object is value-based.
+Two objects of a particular kind are identical if the constituents of
+the objects are identical. For example, two attributes are considered
+the same if they have the same name and the same value. Two characters
+are identical if their Unicode character codes are the same.</para>
+
+<section id="name-classes">
+<title>Name classes</title>
+
+<para>The main semantic concept for name classes is that of a name
+belonging to a name class. A name class is an element that matches the
+production nameClass. A name is as defined in <xref
+linkend="data-model"/>: it consists of a namespace URI and a local
+name.</para>
+
+<para>We use the following notation:</para>
+
+<variablelist>
+
+<varlistentry><term><p:var range="name"/></term><listitem><para>is a variable
+that ranges over names</para></listitem></varlistentry>
+
+<varlistentry><term><p:var range="nameClass"/></term><listitem><para>ranges over name classes</para></listitem></varlistentry>
+
+<varlistentry><term><p:judgement name="belongs">
+ <p:var range="name"/>
+ <p:var range="nameClass"/>
+ </p:judgement></term><listitem><para>
+
+asserts that name <p:var range="name"/> is a member of name class <p:var range="nameClass"/>
+
+</para></listitem></varlistentry>
+
+</variablelist>
+
+<para>We are now ready for our first axiom, which is called "anyName
+1":</para>
+
+<p:proofSystem>
+ <p:rule name="anyName 1">
+ <p:judgement name="belongs">
+ <p:var range="name"/>
+ <p:element name="anyName"/>
+ </p:judgement>
+ </p:rule>
+</p:proofSystem>
+
+<para>This says for any name <p:var range="name"/>, <p:var
+range="name"/> belongs to the name class <p:element name="anyName"/>,
+in other words <p:element name="anyName"/> matches any name. Note the
+effect of the implicit universal quantification over the variables in
+the axiom: this is what makes the axiom apply for any name <p:var
+range="name"/>.</para>
+
+<para>Our first inference rule is almost as simple:</para>
+
+<p:proofSystem>
+ <p:rule name="anyName 2">
+ <p:not>
+ <p:judgement name="belongs">
+ <p:var range="name"/>
+ <p:var range="nameClass"/>
+ </p:judgement>
+ </p:not>
+ <p:judgement name="belongs">
+ <p:var range="name"/>
+ <p:element name="anyName">
+ <p:element name="except">
+ <p:var range="nameClass"/>
+ </p:element>
+ </p:element>
+ </p:judgement>
+ </p:rule>
+
+</p:proofSystem>
+
+<para>This says that for any name <p:var range="name"/>
+and for any name class <p:var range="nameClass"/>,
+if <p:var range="name"/> does not belong to <p:var range="nameClass"/>,
+then <p:var range="name"/> belongs to
+ <p:element name="anyName">
+ <p:element name="except">
+ <p:var range="nameClass"/>
+ </p:element>
+ </p:element>. In other words, <p:element name="anyName">
+ <p:element name="except">
+ <p:var range="nameClass"/>
+ </p:element>
+ </p:element> matches any name that does not match <p:var range="nameClass"/>.</para>
+
+<para>We now need the following additional notation:</para>
+
+<variablelist>
+
+<varlistentry><term><p:var range="ncname"/></term>
+
+<listitem><para>ranges over local names; a local name is a string that
+matches the NCName production of <xref linkend="xml-names"/>, that is,
+a name with no colons</para></listitem>
+</varlistentry>
+
+<varlistentry><term><p:var range="uri"/></term><listitem><para>ranges over URIs</para></listitem></varlistentry>
+
+<varlistentry>
+<term>
+ <p:function name="name">
+ <p:var range="uri"/>
+ <p:var range="ncname"/>
+ </p:function>
+</term>
+<listitem><para>constructs a name with URI <p:var range="uri"/> and local
+name <p:var range="ncname"/></para></listitem>
+</varlistentry>
+
+</variablelist>
+
+<para>The remaining axioms and inference rules for name classes are as
+follows:</para>
+
+<p:proofSystem>
+
+ <p:rule name="nsName 1">
+ <p:judgement name="belongs">
+ <p:function name="name">
+ <p:var range="uri"/>
+ <p:var range="ncname"/>
+ </p:function>
+ <p:element name="nsName">
+ <p:attribute name="ns">
+ <p:var range="uri"/>
+ </p:attribute>
+ </p:element>
+ </p:judgement>
+ </p:rule>
+
+ <p:rule name="nsName 2">
+ <p:not>
+ <p:judgement name="belongs">
+ <p:function name="name">
+ <p:var range="uri"/>
+ <p:var range="ncname"/>
+ </p:function>
+ <p:var range="nameClass"/>
+ </p:judgement>
+ </p:not>
+ <p:judgement name="belongs">
+ <p:function name="name">
+ <p:var range="uri"/>
+ <p:var range="ncname"/>
+ </p:function>
+ <p:element name="nsName">
+ <p:attribute name="ns">
+ <p:var range="uri"/>
+ </p:attribute>
+ <p:element name="except">
+ <p:var range="nameClass"/>
+ </p:element>
+ </p:element>
+ </p:judgement>
+ </p:rule>
+
+ <p:rule name="name">
+ <p:judgement name="belongs">
+ <p:function name="name">
+ <p:var range="uri"/>
+ <p:var range="ncname"/>
+ </p:function>
+ <p:element name="name">
+ <p:attribute name="ns">
+ <p:var range="uri"/>
+ </p:attribute>
+ <p:var range="ncname"/>
+ </p:element>
+ </p:judgement>
+ </p:rule>
+
+ <p:rule name="name choice 1">
+ <p:judgement name="belongs">
+ <p:var range="name"/>
+ <p:var range="nameClass" sub="1"/>
+ </p:judgement>
+ <p:judgement name="belongs">
+ <p:var range="name"/>
+ <p:element name="choice">
+ <p:var range="nameClass" sub="1"/>
+ <p:var range="nameClass" sub="2"/>
+ </p:element>
+ </p:judgement>
+ </p:rule>
+
+ <p:rule name="name choice 2">
+ <p:judgement name="belongs">
+ <p:var range="name"/>
+ <p:var range="nameClass" sub="2"/>
+ </p:judgement>
+ <p:judgement name="belongs">
+ <p:var range="name"/>
+ <p:element name="choice">
+ <p:var range="nameClass" sub="1"/>
+ <p:var range="nameClass" sub="2"/>
+ </p:element>
+ </p:judgement>
+ </p:rule>
+
+</p:proofSystem>
+
+</section>
+
+
+<section>
+<title>Patterns</title>
+
+<para>The axioms and inference rules for patterns use the following
+notation:</para>
+
+<variablelist>
+
+<varlistentry><term><p:var range="context"/></term><listitem><para>ranges
+over contexts (as defined in <xref
+linkend="data-model"/>)</para></listitem></varlistentry>
+
+<varlistentry><term><p:var range="att"/></term><listitem><para>ranges over
+sets of attributes; a set with a single member
+is considered the same as that member</para></listitem></varlistentry>
+
+<varlistentry><term><p:var
+range="mixed"/></term><listitem><para>ranges over sequences of
+elements and strings; a sequence with a single member is considered
+the same as that member; the sequences ranged over by <p:var
+range="mixed"/> may contain consecutive strings and may contain strings
+that are empty; thus, there are sequences ranged over by <p:var
+range="mixed"/> that cannot occur as the children of an
+element</para></listitem></varlistentry>
+
+<varlistentry><term><p:var range="pattern"/></term><listitem><para>ranges
+over patterns (elements matching the pattern
+production)</para></listitem></varlistentry>
+
+<varlistentry><term><p:judgement name="match">
+ <p:var range="context"/>
+ <p:var range="att"/>
+ <p:var range="mixed"/>
+ <p:var range="pattern"/>
+ </p:judgement></term><listitem><para>
+
+asserts that with respect to context <p:var range="context"/>, the
+attributes <p:var range="att"/> and the sequence of elements and
+strings <p:var range="mixed"/> matches the pattern <p:var
+range="pattern"/></para></listitem></varlistentry>
+
+</variablelist>
+
+<section id="choice-pattern">
+<title><literal>choice</literal> pattern</title>
+
+<para>The semantics of the <literal>choice</literal> pattern are as follows:</para>
+
+<p:proofSystem>
+ <p:rule name="choice 1">
+
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:var range="att"/>
+ <p:var range="mixed"/>
+ <p:var range="pattern" sub="1"/>
+ </p:judgement>
+
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:var range="att"/>
+ <p:var range="mixed"/>
+ <p:element name="choice">
+ <p:var range="pattern" sub="1"/>
+ <p:var range="pattern" sub="2"/>
+ </p:element>
+ </p:judgement>
+
+ </p:rule>
+
+ <p:rule name="choice 2">
+
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:var range="att"/>
+ <p:var range="mixed"/>
+ <p:var range="pattern" sub="2"/>
+ </p:judgement>
+
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:var range="att"/>
+ <p:var range="mixed"/>
+ <p:element name="choice">
+ <p:var range="pattern" sub="1"/>
+ <p:var range="pattern" sub="2"/>
+ </p:element>
+ </p:judgement>
+
+ </p:rule>
+
+
+</p:proofSystem>
+
+</section>
+
+<section>
+<title><literal>group</literal> pattern</title>
+
+<para>We use the following additional notation:</para>
+
+<variablelist>
+
+<varlistentry><term><p:function name="append">
+ <p:var range="mixed" sub="1"/>
+ <p:var range="mixed" sub="2"/>
+ </p:function></term><listitem>
+<para>represents the concatenation of the sequences <p:var range="mixed" sub="1"/> and <p:var range="mixed" sub="2"/>
+
+</para></listitem></varlistentry>
+
+<varlistentry><term><p:function name="union">
+ <p:var range="att" sub="1"/>
+ <p:var range="att" sub="2"/>
+ </p:function></term><listitem>
+<para>represents the union of <p:var range="att" sub="1"/>
+and <p:var range="att" sub="2"/></para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+
+<para>The semantics of the <literal>group</literal> pattern are as follows:</para>
+
+<p:proofSystem>
+ <p:rule name="group">
+
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:var range="att" sub="1"/>
+ <p:var range="mixed" sub="1"/>
+ <p:var range="pattern" sub="1"/>
+ </p:judgement>
+
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:var range="att" sub="2"/>
+ <p:var range="mixed" sub="2"/>
+ <p:var range="pattern" sub="2"/>
+ </p:judgement>
+
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:function name="union">
+ <p:var range="att" sub="1"/>
+ <p:var range="att" sub="2"/>
+ </p:function>
+ <p:function name="append">
+ <p:var range="mixed" sub="1"/>
+ <p:var range="mixed" sub="2"/>
+ </p:function>
+ <p:element name="group">
+ <p:var range="pattern" sub="1"/>
+ <p:var range="pattern" sub="2"/>
+ </p:element>
+ </p:judgement>
+
+ </p:rule>
+
+</p:proofSystem>
+
+<note><para>The restriction in <xref linkend="attribute-restrictions"/>
+ensures that the set of attributes constructed in the consequent will
+not have multiple attributes with the same name.</para></note>
+
+</section>
+
+
+<section id="empty-pattern">
+<title><literal>empty</literal> pattern</title>
+
+<para>We use the following additional notation:</para>
+
+<variablelist>
+<varlistentry><term><p:function name="emptySequence"/></term><listitem><para>represents an empty sequence</para></listitem></varlistentry>
+
+<varlistentry><term><p:function name="emptySet"/></term><listitem><para>represents an empty set</para></listitem></varlistentry>
+
+</variablelist>
+
+<para>The semantics of the <literal>empty</literal> pattern are as follows:</para>
+
+<p:proofSystem>
+ <p:rule name="empty">
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:function name="emptySet"/>
+ <p:function name="emptySequence"/>
+ <p:element name="empty"></p:element>
+ <p:function name="emptySet"/>
+ <p:function name="emptySet"/>
+ </p:judgement>
+ </p:rule>
+</p:proofSystem>
+
+</section>
+
+
+<section id="text-pattern">
+<title><literal>text</literal> pattern</title>
+
+<para>We use the following additional notation:</para>
+
+<variablelist>
+<varlistentry><term><p:var range="string"/></term><listitem><para>ranges
+over strings</para></listitem></varlistentry>
+</variablelist>
+
+<para>The semantics of the <literal>text</literal> pattern are as follows:</para>
+
+<p:proofSystem>
+ <p:rule name="text 1">
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:function name="emptySet"/>
+ <p:function name="emptySequence"/>
+ <p:element name="text"></p:element>
+ <p:function name="emptySet"/>
+ <p:function name="emptySet"/>
+ </p:judgement>
+ </p:rule>
+
+ <p:rule name="text 2">
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:function name="emptySet"/>
+ <p:var range="mixed"/>
+ <p:element name="text"></p:element>
+ <p:function name="emptySet"/>
+ <p:function name="emptySet"/>
+ </p:judgement>
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:function name="emptySet"/>
+ <p:function name="append">
+ <p:var range="mixed"/>
+ <p:var range="string"/>
+ </p:function>
+ <p:element name="text"></p:element>
+ <p:function name="emptySet"/>
+ <p:function name="emptySet"/>
+ </p:judgement>
+ </p:rule>
+
+</p:proofSystem>
+
+<para>The effect of the above rule is that a <literal>text</literal>
+element matches zero or more strings.</para>
+
+</section>
+
+
+<section>
+<title><literal>oneOrMore</literal> pattern</title>
+
+<para>We use the following additional notation:</para>
+
+<variablelist>
+<varlistentry><term><p:judgement name="disjoint">
+ <p:var range="att" sub="1"/>
+ <p:var range="att" sub="2"/>
+ </p:judgement></term><listitem><para>
+asserts that there is no name that is
+the name of both an attribute in <p:var range="att" sub="1"/>
+and of an attribute in <p:var range="att" sub="2"/>
+</para></listitem></varlistentry>
+</variablelist>
+
+<para>The semantics of the <literal>oneOrMore</literal> pattern are as follows:</para>
+
+<p:proofSystem>
+ <p:rule name="oneOrMore 1">
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:var range="att"/>
+ <p:var range="mixed"/>
+ <p:var range="pattern"/>
+ </p:judgement>
+
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:var range="att"/>
+ <p:var range="mixed"/>
+ <p:element name="oneOrMore">
+ <p:var range="pattern"/>
+ </p:element>
+ </p:judgement>
+ </p:rule>
+
+ <p:rule name="oneOrMore 2">
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:var range="att" sub="1"/>
+ <p:var range="mixed" sub="1"/>
+ <p:var range="pattern"/>
+ </p:judgement>
+
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:var range="att" sub="2"/>
+ <p:var range="mixed" sub="2"/>
+ <p:element name="oneOrMore">
+ <p:var range="pattern"/>
+ </p:element>
+ </p:judgement>
+
+ <p:judgement name="disjoint">
+ <p:var range="att" sub="1"/>
+ <p:var range="att" sub="2"/>
+ </p:judgement>
+
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:function name="union">
+ <p:var range="att" sub="1"/>
+ <p:var range="att" sub="2"/>
+ </p:function>
+ <p:function name="append">
+ <p:var range="mixed" sub="1"/>
+ <p:var range="mixed" sub="2"/>
+ </p:function>
+ <p:element name="oneOrMore">
+ <p:var range="pattern"/>
+ </p:element>
+ </p:judgement>
+ </p:rule>
+
+</p:proofSystem>
+
+</section>
+
+
+<section>
+<title><literal>interleave</literal> pattern</title>
+
+<para>We use the following additional notation:</para>
+
+<variablelist>
+<varlistentry><term><p:judgement name="interleave">
+ <p:var range="mixed" sub="1"/>
+ <p:var range="mixed" sub="2"/>
+ <p:var range="mixed" sub="3"/>
+ </p:judgement></term><listitem><para>
+
+asserts that <p:var range="mixed" sub="1"/>
+is an interleaving of <p:var range="mixed" sub="2"/>
+and <p:var range="mixed" sub="3"/>
+</para></listitem></varlistentry>
+
+</variablelist>
+
+<para>The semantics of interleaving are defined by the following rules.</para>
+
+
+<p:proofSystem>
+ <p:rule name="interleaves 1">
+
+ <p:judgement name="interleave">
+ <p:function name="emptySequence"/>
+ <p:function name="emptySequence"/>
+ <p:function name="emptySequence"/>
+ </p:judgement>
+
+ </p:rule>
+
+ <p:rule name="interleaves 2">
+
+ <p:judgement name="interleave">
+ <p:var range="mixed" sub="1"/>
+ <p:var range="mixed" sub="2"/>
+ <p:var range="mixed" sub="3"/>
+ </p:judgement>
+
+ <p:judgement name="interleave">
+ <p:function name="append">
+ <p:var range="mixed" sub="4"/>
+ <p:var range="mixed" sub="1"/>
+ </p:function>
+ <p:function name="append">
+ <p:var range="mixed" sub="4"/>
+ <p:var range="mixed" sub="2"/>
+ </p:function>
+ <p:var range="mixed" sub="3"/>
+ </p:judgement>
+
+ </p:rule>
+
+ <p:rule name="interleaves 3">
+
+ <p:judgement name="interleave">
+ <p:var range="mixed" sub="1"/>
+ <p:var range="mixed" sub="2"/>
+ <p:var range="mixed" sub="3"/>
+ </p:judgement>
+
+ <p:judgement name="interleave">
+ <p:function name="append">
+ <p:var range="mixed" sub="4"/>
+ <p:var range="mixed" sub="1"/>
+ </p:function>
+ <p:var range="mixed" sub="2"/>
+ <p:function name="append">
+ <p:var range="mixed" sub="4"/>
+ <p:var range="mixed" sub="3"/>
+ </p:function>
+ </p:judgement>
+
+ </p:rule>
+
+</p:proofSystem>
+
+<para>For example, the interleavings of
+<literal><![CDATA[<a/><a/>]]></literal> and
+<literal><![CDATA[<b/>]]></literal> are
+<literal><![CDATA[<a/><a/><b/>]]></literal>,
+<literal><![CDATA[<a/><b/><a/>]]></literal>, and
+<literal><![CDATA[<b/><a/><a/>]]></literal>.</para>
+
+<para>The semantics of the <literal>interleave</literal> pattern are
+as follows:</para>
+
+<p:proofSystem>
+ <p:rule name="interleave">
+
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:var range="att" sub="1"/>
+ <p:var range="mixed" sub="1"/>
+ <p:var range="pattern" sub="1"/>
+ </p:judgement>
+
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:var range="att" sub="2"/>
+ <p:var range="mixed" sub="2"/>
+ <p:var range="pattern" sub="2"/>
+ </p:judgement>
+
+ <p:judgement name="interleave">
+ <p:var range="mixed" sub="3"/>
+ <p:var range="mixed" sub="1"/>
+ <p:var range="mixed" sub="2"/>
+ </p:judgement>
+
+
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:function name="union">
+ <p:var range="att" sub="1"/>
+ <p:var range="att" sub="2"/>
+ </p:function>
+ <p:var range="mixed" sub="3"/>
+ <p:element name="interleave">
+ <p:var range="pattern" sub="1"/>
+ <p:var range="pattern" sub="2"/>
+ </p:element>
+ </p:judgement>
+
+ </p:rule>
+
+</p:proofSystem>
+
+<note><para>The restriction in <xref linkend="attribute-restrictions"/>
+ensures that the set of attributes constructed in the consequent will
+not have multiple attributes with the same name.</para></note>
+
+</section>
+
+<section id="element-pattern">
+<title><literal>element</literal> and <literal>attribute</literal> pattern</title>
+
+<para>The value of an attribute is always a single string, which may
+be empty. Thus, the empty sequence is not a possible attribute value.
+On the hand, the children of an element can be an empty sequence and
+cannot consist of an empty string. In order to ensure that validation
+handles attributes and elements consistently, we introduce a variant
+of matching called <firstterm>weak matching</firstterm>. Weak
+matching is used when matching the pattern for the value of an
+attribute or for the attributes and children of an element. We use
+the following notation to define weak matching.</para>
+
+<variablelist>
+
+<varlistentry><term><p:function
+name="emptyString"/></term><listitem><para>represents an empty
+string</para></listitem></varlistentry>
+
+<varlistentry><term><p:var
+range="whiteSpace"/></term><listitem><para>ranges over the empty
+sequence and strings that consist entirely of
+whitespace</para></listitem></varlistentry>
+
+<varlistentry><term><p:judgement name="weakMatch">
+ <p:var range="context"/>
+ <p:var range="att"/>
+ <p:var range="mixed"/>
+ <p:var range="pattern"/>
+ </p:judgement></term><listitem><para>
+
+asserts that with respect to context <p:var range="context"/>, the
+attributes <p:var range="att"/> and the sequence of elements and
+strings <p:var range="mixed"/> weakly matches the pattern <p:var
+range="pattern"/></para></listitem></varlistentry>
+
+</variablelist>
+
+<para>The semantics of weak matching are as follows:</para>
+
+<p:proofSystem>
+ <p:rule name="weak match 1">
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:var range="att"/>
+ <p:var range="mixed"/>
+ <p:var range="pattern"/>
+ </p:judgement>
+ <p:judgement name="weakMatch">
+ <p:var range="context"/>
+ <p:var range="att"/>
+ <p:var range="mixed"/>
+ <p:var range="pattern"/>
+ </p:judgement>
+ </p:rule>
+ <p:rule name="weak match 2">
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:var range="att"/>
+ <p:function name="emptySequence"/>
+ <p:var range="pattern"/>
+ </p:judgement>
+ <p:judgement name="weakMatch">
+ <p:var range="context"/>
+ <p:var range="att"/>
+ <p:var range="whiteSpace"/>
+ <p:var range="pattern"/>
+ </p:judgement>
+ </p:rule>
+ <p:rule name="weak match 3">
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:var range="att"/>
+ <p:function name="emptyString"/>
+ <p:var range="pattern"/>
+ </p:judgement>
+ <p:judgement name="weakMatch">
+ <p:var range="context"/>
+ <p:var range="att"/>
+ <p:function name="emptySequence"/>
+ <p:var range="pattern"/>
+ </p:judgement>
+ </p:rule>
+</p:proofSystem>
+
+<para>We use the following additional notation:</para>
+
+<variablelist>
+
+<varlistentry><term><p:function name="attribute">
+ <p:var range="name"/>
+ <p:var range="string"/>
+ </p:function></term><listitem><para>
+
+constructs an attribute with name <p:var range="name"/>
+and value <p:var range="string"/>
+</para></listitem></varlistentry>
+
+<varlistentry><term><p:function name="element">
+ <p:var range="name"/>
+ <p:var range="context"/>
+ <p:var range="att"/>
+ <p:var range="mixed"/>
+ </p:function></term><listitem><para>
+
+constructs an element with name <p:var range="name"/>,
+context <p:var range="context"/>,
+attributes <p:var range="att"/>
+and mixed sequence <p:var range="mixed"/> as children
+</para></listitem></varlistentry>
+
+<varlistentry><term><p:judgement name="okAsChildren">
+ <p:var range="mixed"/>
+ </p:judgement></term><listitem><para>
+
+asserts that the mixed sequence <p:var range="mixed"/> can occur as
+the children of an element: it does not contain any member that is an
+empty string, nor does it contain two consecutive members that are
+both strings</para></listitem></varlistentry>
+
+<varlistentry><term><p:judgement name="bind">
+ <p:var range="ncname"/>
+ <p:var range="nameClass"/>
+ <p:var range="pattern"/>
+ </p:judgement></term><listitem><para>
+
+asserts that the grammar contains
+<p:element name="define">
+ <p:attribute name="name">
+ <p:var range="ncname"/>
+ </p:attribute>
+ <p:element name="element">
+ <p:var range="nameClass"/>
+ <p:var range="pattern"/>
+ </p:element>
+</p:element>
+</para></listitem></varlistentry>
+
+</variablelist>
+
+<para>The semantics of the <literal>attribute</literal> pattern are as follows:</para>
+
+<p:proofSystem>
+ <p:rule name="attribute">
+
+ <p:judgement name="weakMatch">
+ <p:var range="context"/>
+ <p:function name="emptySet"/>
+ <p:var range="string"/>
+ <p:var range="pattern"/>
+ </p:judgement>
+
+ <p:judgement name="belongs">
+ <p:var range="name"/>
+ <p:var range="nameClass"/>
+ </p:judgement>
+
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:function name="attribute">
+ <p:var range="name"/>
+ <p:var range="string"/>
+ </p:function>
+ <p:function name="emptySequence"/>
+ <p:element name="attribute">
+ <p:var range="nameClass"/>
+ <p:var range="pattern"/>
+ </p:element>
+ </p:judgement>
+
+ </p:rule>
+
+</p:proofSystem>
+
+<para>The semantics of the <literal>element</literal> pattern are as follows:</para>
+
+<p:proofSystem>
+ <p:rule name="element">
+
+ <p:judgement name="weakMatch">
+ <p:var range="context" sub="1"/>
+ <p:var range="att"/>
+ <p:var range="mixed"/>
+ <p:var range="pattern"/>
+ </p:judgement>
+
+ <p:judgement name="belongs">
+ <p:var range="name"/>
+ <p:var range="nameClass"/>
+ </p:judgement>
+
+ <p:judgement name="okAsChildren">
+ <p:var range="mixed"/>
+ </p:judgement>
+
+ <p:judgement name="bind">
+ <p:var range="ncname"/>
+ <p:var range="nameClass"/>
+ <p:var range="pattern"/>
+ </p:judgement>
+
+ <p:judgement name="match">
+ <p:var range="context" sub="2"/>
+ <p:function name="emptySet"/>
+ <p:function name="append">
+ <p:var range="whiteSpace" sub="1"/>
+ <p:function name="element">
+ <p:var range="name"/>
+ <p:var range="context" sub="1"/>
+ <p:var range="att"/>
+ <p:var range="mixed"/>
+ </p:function>
+ <p:var range="whiteSpace" sub="2"/>
+ </p:function>
+ <p:element name="ref">
+ <p:attribute name="name">
+ <p:var range="ncname"/>
+ </p:attribute>
+ </p:element>
+ </p:judgement>
+
+ </p:rule>
+
+</p:proofSystem>
+
+
+</section>
+
+<section id="data-pattern">
+<title><literal>data</literal> and <literal>value</literal> pattern</title>
+
+<para>RELAX NG relies on datatype libraries to perform datatyping.
+A datatype library is identified by a URI. A datatype within a
+datatype library is identified by an NCName. A datatype library
+provides two services.</para>
+
+<itemizedlist>
+
+<listitem><para>It can determine whether a string is a legal
+representation of a datatype. This service accepts a list of zero or
+more parameters. For example, a string datatype might have a parameter
+specifying the length of a string. The datatype library determines
+what parameters are applicable for each datatype.</para></listitem>
+
+<listitem><para>It can determine whether two strings represent the
+same value of a datatype. This service does not have any
+parameters.</para></listitem>
+
+</itemizedlist>
+
+<para>Both services may make use of the context of a string. For
+example, a datatype representing a QName would use the namespace
+map.</para>
+
+<para>We use the following additional notation:</para>
+
+<variablelist>
+<varlistentry><term><p:judgement name="datatypeAllows">
+ <p:var range="uri"/>
+ <p:var range="ncname"/>
+ <p:var range="params"/>
+ <p:var range="string"/>
+ <p:var range="context"/>
+ </p:judgement></term><listitem><para>
+
+asserts that in the datatype library identified by URI <p:var range="uri"/>, the string <p:var range="string"/> interpreted with
+context <p:var range="context"/> is a legal
+value of datatype <p:var range="ncname"/> with parameters <p:var range="params"/></para></listitem></varlistentry>
+
+<varlistentry><term><p:judgement name="datatypeEqual">
+ <p:var range="uri"/>
+ <p:var range="ncname"/>
+ <p:var range="string" sub="1"/>
+ <p:var range="context" sub="1"/>
+ <p:var range="string" sub="2"/>
+ <p:var range="context" sub="2"/>
+ </p:judgement></term><listitem><para>
+
+asserts that in the datatype library identified by URI <p:var range="uri"/>, string <p:var range="string" sub="1"/> interpreted with
+context <p:var range="context" sub="1"/> represents the same value of
+the datatype <p:var range="ncname"/> as the string <p:var range="string" sub="2"/> interpreted in the context of <p:var range="context" sub="2"/>
+</para></listitem></varlistentry>
+
+<varlistentry><term><p:var range="params"/></term><listitem><para>ranges over sequences of parameters</para></listitem></varlistentry>
+
+<varlistentry><term><p:context>
+ <p:var range="context"/>
+ </p:context></term><listitem><para>
+
+within the start-tag of a pattern refers to the context
+of the pattern element
+</para></listitem></varlistentry>
+
+<varlistentry>
+<term>
+ <p:function name="context">
+ <p:var range="uri"/>
+ <p:var range="context"/>
+ </p:function>
+</term>
+<listitem><para>constructs a context which is the same as <p:var range="context"/>
+except that the default namespace is <p:var range="uri"/>; if <p:var
+range="uri"/> is the empty string, then there is no default namespace
+in the constructed context</para></listitem></varlistentry>
+
+</variablelist>
+
+<para>The datatypeEqual function must be reflexive, transitive
+and symmetric, that is, the following inference rules must hold:</para>
+
+<p:proofSystem>
+ <p:rule name="datatypeEqual reflexive">
+ <p:judgement name="datatypeAllows">
+ <p:var range="uri"/>
+ <p:var range="ncname"/>
+ <p:var range="params"/>
+ <p:var range="string"/>
+ <p:var range="context"/>
+ </p:judgement>
+ <p:judgement name="datatypeEqual">
+ <p:var range="uri"/>
+ <p:var range="ncname"/>
+ <p:var range="string"/>
+ <p:var range="context"/>
+ <p:var range="string"/>
+ <p:var range="context"/>
+ </p:judgement>
+ </p:rule>
+ <p:rule name="datatypeEqual transitive">
+ <p:judgement name="datatypeEqual">
+ <p:var range="uri"/>
+ <p:var range="ncname"/>
+ <p:var range="string" sub="1"/>
+ <p:var range="context" sub="1"/>
+ <p:var range="string" sub="2"/>
+ <p:var range="context" sub="2"/>
+ </p:judgement>
+ <p:judgement name="datatypeEqual">
+ <p:var range="uri"/>
+ <p:var range="ncname"/>
+ <p:var range="string" sub="2"/>
+ <p:var range="context" sub="3"/>
+ <p:var range="string" sub="3"/>
+ <p:var range="context" sub="3"/>
+ </p:judgement>
+ <p:judgement name="datatypeEqual">
+ <p:var range="uri"/>
+ <p:var range="ncname"/>
+ <p:var range="string" sub="1"/>
+ <p:var range="context" sub="1"/>
+ <p:var range="string" sub="3"/>
+ <p:var range="context" sub="3"/>
+ </p:judgement>
+ </p:rule>
+ <p:rule name="datatypeEqual symmetric">
+ <p:judgement name="datatypeEqual">
+ <p:var range="uri"/>
+ <p:var range="ncname"/>
+ <p:var range="string" sub="1"/>
+ <p:var range="context" sub="1"/>
+ <p:var range="string" sub="2"/>
+ <p:var range="context" sub="2"/>
+ </p:judgement>
+ <p:judgement name="datatypeEqual">
+ <p:var range="uri"/>
+ <p:var range="ncname"/>
+ <p:var range="string" sub="2"/>
+ <p:var range="context" sub="2"/>
+ <p:var range="string" sub="1"/>
+ <p:var range="context" sub="1"/>
+ </p:judgement>
+ </p:rule>
+</p:proofSystem>
+
+<para>The semantics of the <literal>data</literal> and
+<literal>value</literal> patterns are as follows:</para>
+
+<p:proofSystem>
+ <p:rule name="value">
+ <p:judgement name="datatypeEqual">
+ <p:var range="uri" sub="1"/>
+ <p:var range="ncname"/>
+ <p:var range="string" sub="1"/>
+ <p:var range="context" sub="1"/>
+ <p:var range="string" sub="2"/>
+ <p:function name="context">
+ <p:var range="uri" sub="2"/>
+ <p:var range="context" sub="2"/>
+ </p:function>
+ </p:judgement>
+ <p:judgement name="match">
+ <p:var range="context" sub="1"/>
+ <p:function name="emptySet"/>
+ <p:var range="string" sub="1"/>
+ <p:element name="value">
+ <p:attribute name="datatypeLibrary">
+ <p:var range="uri" sub="1"/>
+ </p:attribute>
+ <p:attribute name="type">
+ <p:var range="ncname"/>
+ </p:attribute>
+ <p:attribute name="ns">
+ <p:var range="uri" sub="2"/>
+ </p:attribute>
+ <p:context>
+ <p:var range="context" sub="2"/>
+ </p:context>
+ <p:var range="string" sub="2"/>
+ </p:element>
+ <p:function name="emptySet"/>
+ <p:function name="emptySet"/>
+ </p:judgement>
+ </p:rule>
+
+ <p:rule name="data 1">
+ <p:judgement name="datatypeAllows">
+ <p:var range="uri"/>
+ <p:var range="ncname"/>
+ <p:var range="params"/>
+ <p:var range="string"/>
+ <p:var range="context"/>
+ </p:judgement>
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:function name="emptySet"/>
+ <p:var range="string"/>
+ <p:element name="data">
+ <p:attribute name="datatypeLibrary">
+ <p:var range="uri"/>
+ </p:attribute>
+ <p:attribute name="type">
+ <p:var range="ncname"/>
+ </p:attribute>
+ <p:var range="params"/>
+ </p:element>
+ <p:function name="emptySet"/>
+ <p:function name="emptySet"/>
+ </p:judgement>
+ </p:rule>
+
+ <p:rule name="data 2">
+ <p:judgement name="datatypeAllows">
+ <p:var range="uri"/>
+ <p:var range="ncname"/>
+ <p:var range="params"/>
+ <p:var range="string"/>
+ <p:var range="context"/>
+ </p:judgement>
+ <p:not>
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:var range="att"/>
+ <p:var range="string"/>
+ <p:var range="pattern"/>
+ </p:judgement>
+ </p:not>
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:function name="emptySet"/>
+ <p:var range="string"/>
+ <p:element name="data">
+ <p:attribute name="datatypeLibrary">
+ <p:var range="uri"/>
+ </p:attribute>
+ <p:attribute name="type">
+ <p:var range="ncname"/>
+ </p:attribute>
+ <p:var range="params"/>
+ <p:element name="except">
+ <p:var range="pattern"/>
+ </p:element>
+ </p:element>
+ <p:function name="emptySet"/>
+ <p:function name="emptySet"/>
+ </p:judgement>
+ </p:rule>
+
+</p:proofSystem>
+
+</section>
+
+<section id="built-in-datatype">
+<title>Built-in datatype library</title>
+
+<para>The empty URI identifies a special built-in datatype library.
+This provides two datatypes, <literal>string</literal> and
+<literal>token</literal>. No parameters are allowed for either of
+these datatypes.</para>
+
+<variablelist>
+<varlistentry><term>
+ <p:judgement name="equal">
+ <p:var range="string" sub="1"/>
+ <p:var range="string" sub="2"/>
+ </p:judgement></term>
+<listitem><para>asserts that <p:var range="string" sub="1"/>
+and <p:var range="string" sub="2"/> are identical</para></listitem>
+</varlistentry>
+
+<varlistentry><term>
+ <p:function name="normalizeWhiteSpace">
+ <p:var range="string"/>
+ </p:function>
+</term>
+<listitem><para>returns the string <p:var range="string"/>,
+with leading and trailing whitespace characters removed,
+and with each other maximal sequence of whitespace characters
+replaced by a single space character </para></listitem>
+</varlistentry>
+</variablelist>
+
+<para>The semantics of the two built-in datatypes are as
+follows:</para>
+
+<p:proofSystem>
+
+ <p:rule name="string allows">
+ <p:judgement name="datatypeAllows">
+ <p:function name="emptyString"/>
+ <p:string>string</p:string>
+ <p:function name="emptySequence"/>
+ <p:var range="string"/>
+ <p:var range="context"/>
+ </p:judgement>
+ </p:rule>
+
+ <p:rule name="string equal">
+ <p:judgement name="datatypeEqual">
+ <p:function name="emptyString"/>
+ <p:string>string</p:string>
+ <p:var range="string"/>
+ <p:var range="context" sub="1"/>
+ <p:var range="string"/>
+ <p:var range="context" sub="2"/>
+ </p:judgement>
+ </p:rule>
+
+ <p:rule name="token allows">
+ <p:judgement name="datatypeAllows">
+ <p:function name="emptyString"/>
+ <p:string>token</p:string>
+ <p:function name="emptySequence"/>
+ <p:var range="string"/>
+ <p:var range="context"/>
+ </p:judgement>
+ </p:rule>
+
+ <p:rule name="token equal">
+ <p:judgement name="equal">
+ <p:function name="normalizeWhiteSpace">
+ <p:var range="string" sub="1"/>
+ </p:function>
+ <p:function name="normalizeWhiteSpace">
+ <p:var range="string" sub="2"/>
+ </p:function>
+ </p:judgement>
+ <p:judgement name="datatypeEqual">
+ <p:function name="emptyString"/>
+ <p:string>token</p:string>
+ <p:var range="string" sub="1"/>
+ <p:var range="context" sub="1"/>
+ <p:var range="string" sub="2"/>
+ <p:var range="context" sub="2"/>
+ </p:judgement>
+ </p:rule>
+
+</p:proofSystem>
+
+</section>
+
+<section>
+<title><literal>list</literal> pattern</title>
+
+<para>We use the following additional notation:</para>
+
+<variablelist>
+<varlistentry><term><p:function name="split">
+ <p:var range="string"/>
+ </p:function></term><listitem><para>
+
+returns a sequence of strings one for each whitespace delimited token
+of <p:var range="string"/>; each string in the returned sequence will
+be non-empty and will not contain any
+whitespace</para></listitem></varlistentry>
+
+</variablelist>
+
+<para>The semantics of the <literal>list</literal> pattern are as follows:</para>
+
+<p:proofSystem>
+ <p:rule name="list">
+
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:function name="emptySet"/>
+ <p:function name="split">
+ <p:var range="string"/>
+ </p:function>
+ <p:var range="pattern"/>
+ </p:judgement>
+
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:function name="emptySet"/>
+ <p:var range="string"/>
+ <p:element name="list">
+ <p:var range="pattern"/>
+ </p:element>
+ </p:judgement>
+
+ </p:rule>
+</p:proofSystem>
+
+<note><para>It is crucial in the above inference rule that the
+sequence that is matched against a pattern can contain consecutive
+strings.</para></note>
+
+</section>
+
+</section>
+
+<section id="validity">
+<title>Validity</title>
+
+<para>Now we can define when an element is valid with respect to a
+schema. We use the following additional notation:</para>
+
+<variablelist>
+
+<varlistentry><term><p:var range="element"/></term><listitem><para>ranges over elements</para></listitem></varlistentry>
+
+<varlistentry><term><p:judgement name="valid">
+ <p:var range="element"/>
+ </p:judgement></term><listitem><para>
+
+asserts that the element <p:var range="element"/> is valid with
+respect to the grammar</para></listitem></varlistentry>
+
+<varlistentry><term><p:judgement name="start">
+ <p:var range="pattern"/>
+ </p:judgement></term><listitem><para>
+asserts that the grammar contains
+<p:element name="start"><p:var range="pattern"/> </p:element></para></listitem></varlistentry>
+
+</variablelist>
+
+<para>An element is valid if together with an empty set of attributes
+it matches the <literal>start</literal> pattern of the grammar.</para>
+
+<p:proofSystem>
+ <p:rule name="valid">
+ <p:judgement name="start">
+ <p:var range="pattern"/>
+ </p:judgement>
+ <p:judgement name="match">
+ <p:var range="context"/>
+ <p:function name="emptySet"/>
+ <p:var range="element"/>
+ <p:var range="pattern"/>
+ </p:judgement>
+ <p:judgement name="valid">
+ <p:var range="element"/>
+ </p:judgement>
+ </p:rule>
+
+
+</p:proofSystem>
+
+</section>
+
+<section>
+<title>Example</title>
+
+<para>Let <p:var range="element" sub="0"/> be</para>
+
+<p:formula>
+
+<p:function name="element">
+ <p:function name="name">
+ <p:function name="emptyString"/>
+ <p:string>foo</p:string>
+ </p:function>
+ <p:var range="context" sub="0"/>
+ <p:function name="emptySet"/>
+ <p:var range="mixed"/>
+</p:function>
+
+</p:formula>
+
+<para>where <p:var range="mixed"/> is</para>
+
+<p:formula>
+ <p:function name="append">
+ <p:var range="element" sub="1"/>
+ <p:var range="element" sub="2"/>
+ </p:function>
+</p:formula>
+
+<para>and <p:var range="element" sub="1"/> is</para>
+
+<p:formula>
+ <p:function name="element">
+ <p:function name="name">
+ <p:string>http://www.example.com/n1</p:string>
+ <p:string>bar1</p:string>
+ </p:function>
+ <p:var range="context" sub="1"/>
+ <p:function name="emptySet"/>
+ <p:function name="emptySequence"/>
+ </p:function>
+</p:formula>
+
+<para>and <p:var range="element" sub="2"/> is</para>
+
+<p:formula>
+ <p:function name="element">
+ <p:function name="name">
+ <p:string>http://www.example.com/n2</p:string>
+ <p:string>bar2</p:string>
+ </p:function>
+ <p:var range="context" sub="2"/>
+ <p:function name="emptySet"/>
+ <p:function name="emptySequence"/>
+ </p:function>
+</p:formula>
+
+<para>Assuming appropriate definitions of <p:var range="context"
+sub="0"/>, <p:var range="context" sub="1"/> and <p:var range="context"
+sub="2"/>, this represents the document in <xref
+linkend="data-model-example"/>.</para>
+
+<para>We now show how <p:var range="element" sub="0"/> can be shown to
+be valid with respect to the schema in <xref
+linkend="simple-syntax-example"/>. The schema is equivalent to the
+following propositions:</para>
+
+<p:formula>
+ <p:judgement name="start">
+ <p:element name="ref">
+ <p:attribute name="name"><p:string>foo</p:string></p:attribute>
+ </p:element>
+ </p:judgement>
+</p:formula>
+
+<p:formula>
+ <p:judgement name="bind">
+ <p:string>foo.element</p:string>
+ <p:element name="name">
+ <p:attribute name="ns"><p:function name="emptyString"/></p:attribute>
+ <p:string>foo</p:string>
+ </p:element>
+ <p:element name="group">
+ <p:element name="ref">
+ <p:attribute name="name">
+ <p:string>bar1</p:string>
+ </p:attribute>
+ </p:element>
+ <p:element name="ref">
+ <p:attribute name="name">
+ <p:string>bar2</p:string>
+ </p:attribute>
+ </p:element>
+ </p:element>
+ </p:judgement>
+</p:formula>
+
+<p:formula>
+ <p:judgement name="bind">
+ <p:string>bar1.element</p:string>
+ <p:element name="name">
+ <p:attribute name="ns">
+ <p:string>http://www.example.com/n1</p:string>
+ </p:attribute>
+ <p:string>bar1</p:string>
+ </p:element>
+ <p:element name="empty"/>
+ </p:judgement>
+</p:formula>
+
+<p:formula>
+ <p:judgement name="bind">
+ <p:string>bar2.element</p:string>
+ <p:element name="name">
+ <p:attribute name="ns">
+ <p:string>http://www.example.com/n2</p:string>
+ </p:attribute>
+ <p:string>bar2</p:string>
+ </p:element>
+ <p:element name="empty"/>
+ </p:judgement>
+</p:formula>
+
+
+<para>Let name class <p:var range="nameClass" sub="1"/> be</para>
+
+<p:formula>
+ <p:element name="name">
+ <p:attribute name="ns">
+ <p:string>http://www.example.com/n1</p:string>
+ </p:attribute>
+ <p:string>bar1</p:string>
+ </p:element>
+</p:formula>
+
+<para>and let <p:var range="nameClass" sub="2"/> be</para>
+
+<p:formula>
+ <p:element name="name">
+ <p:attribute name="ns">
+ <p:string>http://www.example.com/n2</p:string>
+ </p:attribute>
+ <p:string>bar2</p:string>
+ </p:element>
+</p:formula>
+
+<para>Then, by the inference rule (name) in <xref
+linkend="name-classes"/>, we have</para>
+
+<p:formula>
+ <p:judgement name="belongs">
+ <p:function name="name">
+ <p:string>http://www.example.com/n1</p:string>
+ <p:string>bar1</p:string>
+ </p:function>
+ <p:var range="nameClass" sub="1"/>
+ </p:judgement>
+</p:formula>
+
+<para>and</para>
+
+<p:formula>
+ <p:judgement name="belongs">
+ <p:function name="name">
+ <p:string>http://www.example.com/n2</p:string>
+ <p:string>bar2</p:string>
+ </p:function>
+ <p:var range="nameClass" sub="2"/>
+ </p:judgement>
+</p:formula>
+
+
+<para>By the inference rule (empty) in <xref linkend="empty-pattern"/>,
+we have</para>
+
+<p:formula>
+ <p:judgement name="match">
+ <p:var range="context" sub="1"/>
+ <p:function name="emptySet"/>
+ <p:function name="emptySequence"/>
+ <p:element name="empty"></p:element>
+ </p:judgement>
+</p:formula>
+
+<para>and</para>
+
+<p:formula>
+ <p:judgement name="match">
+ <p:var range="context" sub="2"/>
+ <p:function name="emptySet"/>
+ <p:function name="emptySequence"/>
+ <p:element name="empty"></p:element>
+ </p:judgement>
+</p:formula>
+
+<para>Thus by the inference rule (element) in <xref
+linkend="element-pattern"/>, we have</para>
+
+<p:formula>
+ <p:judgement name="match">
+ <p:var range="context" sub="0"/>
+ <p:function name="emptySet"/>
+ <p:var range="element" sub="1"/>
+ <p:element name="ref">
+ <p:attribute name="name">
+ <p:string>bar1</p:string>
+ </p:attribute>
+ </p:element>
+ </p:judgement>
+</p:formula>
+
+<para>Note that we have chosen <p:var
+range="context" sub="0"/>, since any context is allowed.</para>
+
+<para>Likewise, we have</para>
+
+<p:formula>
+ <p:judgement name="match">
+ <p:var range="context" sub="0"/>
+ <p:function name="emptySet"/>
+ <p:var range="element" sub="2"/>
+ <p:element name="ref">
+ <p:attribute name="name">
+ <p:string>bar2</p:string>
+ </p:attribute>
+ </p:element>
+ </p:judgement>
+</p:formula>
+
+<para>By the inference rule (group) in <xref
+linkend="choice-pattern"/>, we have</para>
+
+<p:formula>
+ <p:judgement name="match">
+ <p:var range="context" sub="0"/>
+ <p:function name="emptySet"/>
+ <p:function name="append">
+ <p:var range="element" sub="1"/>
+ <p:var range="element" sub="2"/>
+ </p:function>
+ <p:element name="group">
+ <p:element name="ref">
+ <p:attribute name="name">
+ <p:string>bar1</p:string>
+ </p:attribute>
+ </p:element>
+ <p:element name="ref">
+ <p:attribute name="name">
+ <p:string>bar2</p:string>
+ </p:attribute>
+ </p:element>
+ </p:element>
+ </p:judgement>
+</p:formula>
+
+<para>By the inference rule (element) in <xref
+linkend="element-pattern"/>, we have</para>
+
+<p:formula>
+ <p:judgement name="match">
+ <p:var range="context" sub="3"/>
+ <p:function name="emptySet"/>
+ <p:function name="element">
+ <p:function name="name">
+ <p:function name="emptyString"/>
+ <p:string>foo</p:string>
+ </p:function>
+ <p:var range="context" sub="0"/>
+ <p:function name="emptySet"/>
+ <p:var range="mixed"/>
+ </p:function>
+ <p:element name="ref">
+ <p:attribute name="name">
+ <p:string>foo</p:string>
+ </p:attribute>
+ </p:element>
+ </p:judgement>
+</p:formula>
+
+<para>Here <p:var range="context" sub="3"/> is an arbitrary
+context.</para>
+
+<para>Thus we can apply the inference rule (valid) in <xref
+linkend="validity"/> and obtain</para>
+
+<p:formula>
+ <p:judgement name="valid">
+ <p:var range="element" sub="0"/>
+ </p:judgement>
+</p:formula>
+
+</section>
+
+</section>
+
+<section id="restriction">
+<title>Restrictions</title>
+
+<para>The following constraints are all checked after the grammar has
+been transformed to the simple form described in <xref
+linkend="simple-syntax"/>. The purpose of these restrictions is to
+catch user errors and to facilitate implementation.</para>
+
+<section id="contextual-restriction">
+<title>Contextual restrictions</title>
+
+<para>In this section we describe restrictions on where elements are
+allowed in the schema based on the names of the ancestor elements. We
+use the concept of a <firstterm>prohibited path</firstterm> to
+describe these restrictions. A path is a sequence of NCNames separated
+by <literal>/</literal> or <literal>//</literal>.</para>
+
+<itemizedlist>
+
+<listitem><para>An element matches a path
+<replaceable>x</replaceable>, where <replaceable>x</replaceable> is an
+NCName, if and only if the local name of the element is
+<replaceable>x</replaceable></para></listitem>
+
+<listitem><para>An element matches a path
+<replaceable>x</replaceable><literal>/</literal><replaceable>p</replaceable>,
+where <replaceable>x</replaceable> is an NCName and
+<replaceable>p</replaceable> is a path, if and only if the local name
+of the element is <replaceable>x</replaceable> and the element has a
+child that matches <replaceable>p</replaceable></para></listitem>
+
+<listitem><para>An element matches a path
+<replaceable>x</replaceable><literal>//</literal><replaceable>p</replaceable>,
+where <replaceable>x</replaceable> is an NCName and
+<replaceable>p</replaceable> is a path, if and only if the local name
+of the element is <replaceable>x</replaceable> and the element has a
+descendant that matches <replaceable>p</replaceable></para></listitem>
+
+</itemizedlist>
+
+<para>For example, the element</para>
+
+<programlisting><![CDATA[<foo>
+ <bar>
+ <baz/>
+ </bar>
+</foo>]]></programlisting>
+
+<para>matches the paths <literal>foo</literal>,
+<literal>foo/bar</literal>, <literal>foo//bar</literal>,
+<literal>foo//baz</literal>, <literal>foo/bar/baz</literal>,
+<literal>foo/bar//baz</literal> and <literal>foo//bar/baz</literal>,
+but not <literal>foo/baz</literal> or
+<literal>foobar</literal>.</para>
+
+<para>A correct RELAX NG schema must be such that, after
+transformation to the simple form, it does not contain any element
+that matches a prohibited path.</para>
+
+<section>
+<title><literal>attribute</literal> pattern</title>
+
+<para>The following paths are prohibited:</para>
+
+<itemizedlist>
+<listitem><para><literal>attribute//ref</literal></para></listitem>
+<listitem><para><literal>attribute//attribute</literal></para></listitem>
+</itemizedlist>
+
+</section>
+
+<section>
+<title><literal>oneOrMore</literal> pattern</title>
+
+<para>The following paths are prohibited:</para>
+
+<itemizedlist>
+<listitem><para><literal>oneOrMore//group//attribute</literal></para></listitem>
+<listitem><para><literal>oneOrMore//interleave//attribute</literal></para></listitem>
+</itemizedlist>
+
+</section>
+
+<section id="list-restrictions">
+<title><literal>list</literal> pattern</title>
+
+<para>The following paths are prohibited:</para>
+
+<itemizedlist>
+<listitem><para><literal>list//list</literal></para></listitem>
+<listitem><para><literal>list//ref</literal></para></listitem>
+<listitem><para><literal>list//attribute</literal></para></listitem>
+<listitem><para><literal>list//text</literal></para></listitem>
+<listitem><para><literal>list//interleave</literal></para></listitem>
+</itemizedlist>
+</section>
+
+<section id="context-data-except">
+<title><literal>except</literal> in <literal>data</literal> pattern</title>
+
+<para>The following paths are prohibited:</para>
+
+<itemizedlist>
+<listitem><para><literal>data/except//attribute</literal></para></listitem>
+<listitem><para><literal>data/except//ref</literal></para></listitem>
+<listitem><para><literal>data/except//text</literal></para></listitem>
+<listitem><para><literal>data/except//list</literal></para></listitem>
+<listitem><para><literal>data/except//group</literal></para></listitem>
+<listitem><para><literal>data/except//interleave</literal></para></listitem>
+<listitem><para><literal>data/except//oneOrMore</literal></para></listitem>
+<listitem><para><literal>data/except//empty</literal></para></listitem>
+</itemizedlist>
+
+<note><para>This implies that an <literal>except</literal> element
+with a <literal>data</literal> parent can contain only
+<literal>data</literal>, <literal>value</literal> and
+<literal>choice</literal> elements.</para></note>
+
+</section>
+
+<section id="context-start">
+<title><literal>start</literal> element</title>
+
+<para>The following paths are prohibited:</para>
+
+<itemizedlist>
+<listitem><para><literal>start//attribute</literal></para></listitem>
+<listitem><para><literal>start//data</literal></para></listitem>
+<listitem><para><literal>start//value</literal></para></listitem>
+<listitem><para><literal>start//text</literal></para></listitem>
+<listitem><para><literal>start//list</literal></para></listitem>
+<listitem><para><literal>start//group</literal></para></listitem>
+<listitem><para><literal>start//interleave</literal></para></listitem>
+<listitem><para><literal>start//oneOrMore</literal></para></listitem>
+<listitem><para><literal>start//empty</literal></para></listitem>
+</itemizedlist>
+</section>
+
+</section>
+
+<section id="string-sequences">
+<title>String sequences</title>
+
+<para>RELAX NG does not allow a pattern such as:</para>
+
+<programlisting><![CDATA[<element name="foo">
+ <group>
+ <data type="int"/>
+ <element name="bar">
+ <empty/>
+ </element>
+ </group>
+</element>]]></programlisting>
+
+<para>Nor does it allow a pattern such as:</para>
+
+<programlisting><![CDATA[<element name="foo">
+ <group>
+ <data type="int"/>
+ <text/>
+ </group>
+</element>]]></programlisting>
+
+<para>More generally, if the pattern for the content of an element or
+attribute contains</para>
+
+<itemizedlist>
+
+<listitem><para>a pattern that can match a child
+(that is, an <literal>element</literal>, <literal>data</literal>,
+<literal>value</literal>, <literal>list</literal> or
+<literal>text</literal> pattern), and</para></listitem>
+
+<listitem><para>a pattern that matches a single string (that is, a
+<literal>data</literal>, <literal>value</literal> or
+<literal>list</literal> pattern),</para></listitem>
+
+</itemizedlist>
+
+<para>then the two patterns must be alternatives to each other.</para>
+
+<para>This rule does not apply to patterns occurring within a
+<literal>list</literal> pattern.</para>
+
+<para>To formalize this, we use the concept of a content-type. A
+pattern that is allowable as the content of an element has one of
+three content-types: empty, complex and simple. We use the following
+notation.</para>
+
+<variablelist>
+
+<varlistentry>
+<term><p:function name="empty"/></term>
+<listitem><para>returns the empty content-type</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><p:function name="complex"/></term>
+<listitem><para>returns the complex content-type</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><p:function name="simple"/></term>
+<listitem><para>returns the simple content-type</para></listitem>
+</varlistentry>
+
+<varlistentry><term><p:var range="contentType"/></term>
+<listitem><para>ranges over content-types</para></listitem>
+</varlistentry>
+
+<varlistentry><term>
+ <p:judgement name="groupable">
+ <p:var range="contentType" sub="1"/>
+ <p:var range="contentType" sub="2"/>
+ </p:judgement>
+</term>
+<listitem><para>asserts that the content-types <p:var
+range="contentType" sub="1"/> and <p:var range="contentType" sub="2"/>
+are groupable</para></listitem>
+</varlistentry>
+
+</variablelist>
+
+<para>The empty content-type is groupable with anything. In addition,
+the complex content-type is groupable with the complex content-type. The
+following rules formalize this.</para>
+
+<p:proofSystem>
+<p:rule name="group empty 1">
+ <p:judgement name="groupable">
+ <p:function name="empty"/>
+ <p:var range="contentType"/>
+ </p:judgement>
+</p:rule>
+<p:rule name="group empty 2">
+ <p:judgement name="groupable">
+ <p:var range="contentType"/>
+ <p:function name="empty"/>
+ </p:judgement>
+</p:rule>
+<p:rule name="group complex">
+ <p:judgement name="groupable">
+ <p:function name="complex"/>
+ <p:function name="complex"/>
+ </p:judgement>
+</p:rule>
+</p:proofSystem>
+
+<para>Some patterns have a content-type. We use the following
+additional notation.</para>
+
+<variablelist>
+
+<varlistentry><term>
+ <p:judgement name="contentType">
+ <p:var range="pattern"/>
+ <p:var range="contentType"/>
+ </p:judgement>
+</term>
+<listitem><para>asserts that pattern <p:var range="pattern"/> has
+content-type <p:var range="contentType"/></para></listitem>
+</varlistentry>
+
+<varlistentry><term>
+ <p:function name="max">
+ <p:var range="contentType" sub="1"/>
+ <p:var range="contentType" sub="2"/>
+ </p:function>
+</term>
+<listitem><para>returns the maximum of <p:var range="contentType"
+sub="1"/> and <p:var range="contentType" sub="2"/> where the
+content-types in increasing order are <p:function name="empty"/>,
+<p:function name="complex"/>, <p:function
+name="simple"/></para></listitem>
+</varlistentry>
+
+</variablelist>
+
+<para>The following rules define when a pattern has a content-type and,
+if so, what it is.</para>
+
+<p:proofSystem>
+<p:rule name="value">
+ <p:judgement name="contentType">
+ <p:element name="value">
+ <p:attribute name="datatypeLibrary">
+ <p:var range="uri" sub="1"/>
+ </p:attribute>
+ <p:attribute name="type">
+ <p:var range="ncname"/>
+ </p:attribute>
+ <p:attribute name="ns">
+ <p:var range="uri" sub="2"/>
+ </p:attribute>
+ <p:var range="string"/>
+ </p:element>
+ <p:function name="simple"/>
+ </p:judgement>
+</p:rule>
+
+<p:rule name="data 1">
+ <p:judgement name="contentType">
+ <p:element name="data">
+ <p:attribute name="datatypeLibrary">
+ <p:var range="uri"/>
+ </p:attribute>
+ <p:attribute name="type">
+ <p:var range="ncname"/>
+ </p:attribute>
+ <p:var range="params"/>
+ </p:element>
+ <p:function name="simple"/>
+ </p:judgement>
+</p:rule>
+
+<p:rule name="data 2">
+ <p:judgement name="contentType">
+ <p:var range="pattern"/>
+ <p:var range="contentType"/>
+ </p:judgement>
+ <p:judgement name="contentType">
+ <p:element name="data">
+ <p:attribute name="datatypeLibrary">
+ <p:var range="uri"/>
+ </p:attribute>
+ <p:attribute name="type">
+ <p:var range="ncname"/>
+ </p:attribute>
+ <p:var range="params"/>
+ <p:element name="except">
+ <p:var range="pattern"/>
+ </p:element>
+ </p:element>
+ <p:function name="simple"/>
+ </p:judgement>
+</p:rule>
+
+<p:rule name="list">
+ <p:judgement name="contentType">
+ <p:element name="list">
+ <p:var range="pattern"/>
+ </p:element>
+ <p:function name="simple"/>
+ </p:judgement>
+</p:rule>
+
+<p:rule name="text">
+ <p:judgement name="contentType">
+ <p:element name="text"/>
+ <p:function name="complex"/>
+ </p:judgement>
+</p:rule>
+
+<p:rule name="ref">
+ <p:judgement name="contentType">
+ <p:element name="ref">
+ <p:attribute name="name">
+ <p:var range="ncname"/>
+ </p:attribute>
+ </p:element>
+ <p:function name="complex"/>
+ </p:judgement>
+</p:rule>
+
+<p:rule name="empty">
+ <p:judgement name="contentType">
+ <p:element name="empty"/>
+ <p:function name="empty"/>
+ </p:judgement>
+</p:rule>
+
+<p:rule name="attribute">
+ <p:judgement name="contentType">
+ <p:var range="pattern"/>
+ <p:var range="contentType"/>
+ </p:judgement>
+ <p:judgement name="contentType">
+ <p:element name="attribute">
+ <p:var range="nameClass"/>
+ <p:var range="pattern"/>
+ </p:element>
+ <p:function name="empty"/>
+ </p:judgement>
+</p:rule>
+
+<p:rule name="group">
+ <p:judgement name="contentType">
+ <p:var range="pattern" sub="1"/>
+ <p:var range="contentType" sub="1"/>
+ </p:judgement>
+ <p:judgement name="contentType">
+ <p:var range="pattern" sub="2"/>
+ <p:var range="contentType" sub="2"/>
+ </p:judgement>
+ <p:judgement name="groupable">
+ <p:var range="contentType" sub="1"/>
+ <p:var range="contentType" sub="2"/>
+ </p:judgement>
+ <p:judgement name="contentType">
+ <p:element name="group">
+ <p:var range="pattern" sub="1"/>
+ <p:var range="pattern" sub="2"/>
+ </p:element>
+ <p:function name="max">
+ <p:var range="contentType" sub="1"/>
+ <p:var range="contentType" sub="2"/>
+ </p:function>
+ </p:judgement>
+</p:rule>
+
+<p:rule name="interleave">
+ <p:judgement name="contentType">
+ <p:var range="pattern" sub="1"/>
+ <p:var range="contentType" sub="1"/>
+ </p:judgement>
+ <p:judgement name="contentType">
+ <p:var range="pattern" sub="2"/>
+ <p:var range="contentType" sub="2"/>
+ </p:judgement>
+ <p:judgement name="groupable">
+ <p:var range="contentType" sub="1"/>
+ <p:var range="contentType" sub="2"/>
+ </p:judgement>
+ <p:judgement name="contentType">
+ <p:element name="interleave">
+ <p:var range="pattern" sub="1"/>
+ <p:var range="pattern" sub="2"/>
+ </p:element>
+ <p:function name="max">
+ <p:var range="contentType" sub="1"/>
+ <p:var range="contentType" sub="2"/>
+ </p:function>
+ </p:judgement>
+</p:rule>
+
+<p:rule name="oneOrMore">
+ <p:judgement name="contentType">
+ <p:var range="pattern"/>
+ <p:var range="contentType"/>
+ </p:judgement>
+ <p:judgement name="groupable">
+ <p:var range="contentType"/>
+ <p:var range="contentType"/>
+ </p:judgement>
+ <p:judgement name="contentType">
+ <p:element name="oneOrMore">
+ <p:var range="pattern"/>
+ </p:element>
+ <p:var range="contentType"/>
+ </p:judgement>
+</p:rule>
+
+<p:rule name="choice">
+ <p:judgement name="contentType">
+ <p:var range="pattern" sub="1"/>
+ <p:var range="contentType" sub="1"/>
+ </p:judgement>
+ <p:judgement name="contentType">
+ <p:var range="pattern" sub="2"/>
+ <p:var range="contentType" sub="2"/>
+ </p:judgement>
+ <p:judgement name="contentType">
+ <p:element name="choice">
+ <p:var range="pattern" sub="1"/>
+ <p:var range="pattern" sub="2"/>
+ </p:element>
+ <p:function name="max">
+ <p:var range="contentType" sub="1"/>
+ <p:var range="contentType" sub="2"/>
+ </p:function>
+ </p:judgement>
+</p:rule>
+
+</p:proofSystem>
+
+<note><para>The antecedent in the (data 2) rule above is in fact
+redundant because of the prohibited paths in <xref
+linkend="context-data-except"/>.</para></note>
+
+<para>Now we can describe the restriction. We use the following
+notation.</para>
+
+<variablelist>
+
+<varlistentry><term>
+ <p:judgement name="incorrectSchema"/>
+</term>
+<listitem><para>asserts that the schema is incorrect</para></listitem>
+</varlistentry>
+
+</variablelist>
+
+<para>All patterns occurring as the content of an element pattern must
+have a content-type.</para>
+
+<p:proofSystem>
+
+<p:rule name="element">
+ <p:judgement name="bind">
+ <p:var range="ncname"/>
+ <p:var range="nameClass"/>
+ <p:var range="pattern"/>
+ </p:judgement>
+ <p:not>
+ <p:judgement name="contentType">
+ <p:var range="pattern"/>
+ <p:var range="contentType"/>
+ </p:judgement>
+ </p:not>
+ <p:judgement name="incorrectSchema"/>
+</p:rule>
+
+</p:proofSystem>
+
+</section>
+
+<section id="attribute-restrictions">
+<title>Restrictions on attributes</title>
+
+<para>Duplicate attributes are not allowed. More precisely, for a
+pattern <literal><group> <replaceable>p1</replaceable>
+<replaceable>p2</replaceable> </group></literal> or
+<literal><interleave> <replaceable>p1</replaceable>
+<replaceable>p2</replaceable> </interleave></literal>, there must
+not be a name that belongs to both the name class of an
+<literal>attribute</literal> pattern occurring in
+<replaceable>p1</replaceable> and the name class of an
+<literal>attribute</literal> pattern occurring in
+<replaceable>p2</replaceable>. A pattern <replaceable>p1</replaceable>
+is defined to <firstterm>occur in</firstterm> a pattern
+<replaceable>p2</replaceable> if</para>
+
+<itemizedlist>
+
+<listitem><para><replaceable>p1</replaceable> is
+<replaceable>p2</replaceable>, or</para></listitem>
+
+<listitem><para><replaceable>p2</replaceable> is a
+<literal>choice</literal>, <literal>interleave</literal>,
+<literal>group</literal> or <literal>oneOrMore</literal> element and
+<replaceable>p1</replaceable> occurs in one or more children of
+<replaceable>p2</replaceable>.</para></listitem>
+
+</itemizedlist>
+
+<para>Attributes using infinite name classes must be repeated. More
+precisely, an <literal>attribute</literal> element that has an
+<literal>anyName</literal> or <literal>nsName</literal> descendant
+element must have a <literal>oneOrMore</literal> ancestor
+element.</para>
+
+<note><para>This restriction is necessary for closure under
+negation.</para></note>
+
+</section>
+
+<section id="interleave-restrictions">
+<title>Restrictions on <literal>interleave</literal></title>
+
+<para>For a pattern <literal><interleave>
+<replaceable>p1</replaceable> <replaceable>p2</replaceable>
+</interleave></literal>,</para>
+
+<itemizedlist>
+
+<listitem><para>there must not be a name that belongs to both the name
+class of an <literal>element</literal> pattern referenced by a
+<literal>ref</literal> pattern occurring in
+<replaceable>p1</replaceable> and the name class of an
+<literal>element</literal> pattern referenced by a
+<literal>ref</literal> pattern occurring in
+<replaceable>p2</replaceable>, and</para></listitem>
+
+<listitem><para>a <literal>text</literal> pattern must not occur in
+both <replaceable>p1</replaceable> and
+<replaceable>p2</replaceable>.</para></listitem>
+
+</itemizedlist>
+
+<para><xref linkend="attribute-restrictions"/> defines when one
+pattern is considered to occur in another pattern.</para>
+
+</section>
+
+</section>
+
+<section id="conformance">
+<title>Conformance</title>
+
+<para>A conforming RELAX NG validator must be able to determine for
+any XML document whether it is a correct RELAX NG schema. A
+conforming RELAX NG validator must be able to determine for any XML
+document and for any correct RELAX NG schema whether the document is
+valid with respect to the schema.</para>
+
+<para>However, the requirements in the preceding paragraph do not
+apply if the schema uses a datatype library that the validator does
+not support. A conforming RELAX NG validator is only required to
+support the built-in datatype library described in <xref
+linkend="built-in-datatype"/>. A validator that claims conformance to
+RELAX NG should document which datatype libraries it supports. The
+requirements in the preceding paragraph also do not apply if the
+schema includes <literal>externalRef</literal> or
+<literal>include</literal> elements and the validator is unable to
+retrieve the resource identified by the URI or is unable to construct
+an element from the retrieved resource. A validator that claims
+conformance to RELAX NG should document its capabilities for handling
+URI references.</para>
+
+</section>
+
+<appendix>
+<title>RELAX NG schema for RELAX NG</title>
+
+<rngref src="relaxng.rng"/>
+
+</appendix>
+
+<appendix>
+<title>Changes since version 0.9</title>
+
+<para>The changes in this version relative to version 0.9
+are as follows:</para>
+
+<itemizedlist>
+
+<listitem><para>in the namespace URI, <literal>0.9</literal> has been
+changed to <literal>1.0</literal></para></listitem>
+
+<listitem><para><literal>data/except//empty</literal> has been added
+as a prohibited path (see <xref
+linkend="context-data-except"/>)</para></listitem>
+
+<listitem><para><literal>start//empty</literal> has been added
+as a prohibited path (see <xref
+linkend="context-start"/>)</para></listitem>
+
+<listitem><para><xref linkend="number-child-elements"/> now specifies how a
+<literal>list</literal> element with more than one child element is
+transformed</para></listitem>
+
+<listitem><para><xref linkend="notAllowed"/> now specifies how a
+<literal>notAllowed</literal> element occurring in an
+<literal>except</literal> element is transformed</para></listitem>
+
+<listitem><para>although a relative URI is not allowed as the value of
+the <literal>ns</literal> and <literal>datatypeLibrary</literal>
+attributes, an empty string is allowed (see <xref
+linkend="full-syntax"/>)</para></listitem>
+
+<listitem><para>the removal of unreachable definitions in <xref
+linkend="define-ref"/> is now correctly specified</para></listitem>
+
+<listitem><para><xref linkend="notAllowed"/> now specifies that
+<literal>define</literal> elements that are no longer reachable are
+removed</para></listitem>
+
+<listitem><para><xref linkend="constraints"/> has been added; the
+restrictions on the contents of <literal>except</literal> in name
+classes that are now specified in the newly added section were
+previously specified in a subsection of <xref
+linkend="contextual-restriction"/>, which has been
+removed</para></listitem>
+
+<listitem><para>the treatment of element and attribute values that
+consist only of whitespace has been refined (see <xref
+linkend="element-pattern"/> and <xref
+linkend="data-pattern"/>)</para></listitem>
+
+<listitem><para>attributes with infinite name classes are now required
+to be repeated (see <xref
+linkend="attribute-restrictions"/>)</para></listitem>
+
+<listitem><para>restrictions have been imposed on
+<literal>interleave</literal> (see <xref
+linkend="interleave-restrictions"/>); <literal>list//interleave</literal>
+has been added as a prohibited path (see <xref
+linkend="list-restrictions"/>)</para></listitem>
+
+<listitem><para>some of the prohibited paths in <xref
+linkend="contextual-restriction"/> have been corrected to use
+<literal>ref</literal> rather than
+<literal>element</literal></para></listitem>
+
+<listitem><para>an error in the inference rule (text 1) in <xref
+linkend="text-pattern"/> has been corrected</para></listitem>
+
+<listitem><para>the value of the <literal>ns</literal> attribute is
+now unconstrained (see <xref
+linkend="full-syntax"/>)</para></listitem>
+
+</itemizedlist>
+
+</appendix>
+
+<appendix>
+<title>RELAX NG TC (Non-Normative)</title>
+
+<para>This specification was prepared and approved for publication by
+the RELAX NG TC. The current members of the TC are:</para>
+
+<itemizedlist>
+<listitem><para>Fabio Arciniegas</para></listitem>
+<listitem><para>James Clark</para></listitem>
+<listitem><para>Mike Fitzgerald</para></listitem>
+<listitem><para>KAWAGUCHI Kohsuke</para></listitem>
+<listitem><para>Josh Lubell</para></listitem>
+<listitem><para>MURATA Makoto</para></listitem>
+<listitem><para>Norman Walsh</para></listitem>
+<listitem><para>David Webber</para></listitem>
+</itemizedlist>
+
+</appendix>
+
+<bibliography><title>References</title>
+
+<bibliodiv><title>Normative</title>
+
+<bibliomixed id="xml-rec"><abbrev>XML 1.0</abbrev>Tim Bray,
+Jean Paoli, and
+C. M. Sperberg-McQueen, Eve Maler, editors.
+<citetitle><ulink url="http://www.w3.org/TR/REC-xml">Extensible Markup
+Language (XML) 1.0 Second Edition</ulink></citetitle>.
+W3C (World Wide Web Consortium), 2000.</bibliomixed>
+
+<bibliomixed id="xml-names"><abbrev>XML Namespaces</abbrev>Tim Bray,
+Dave Hollander,
+and Andrew Layman, editors.
+<citetitle><ulink url="http://www.w3.org/TR/REC-xml-names/">Namespaces in
+XML</ulink></citetitle>.
+W3C (World Wide Web Consortium), 1999.</bibliomixed>
+
+<bibliomixed id="xlink"><abbrev>XLink</abbrev>Steve DeRose, Eve Maler
+and David Orchard, editors.
+<citetitle><ulink url="http://www.w3.org/TR/xlink/">XML Linking
+Language (XLink) Version 1.0</ulink></citetitle>.
+W3C (World Wide Web Consortium), 2001.</bibliomixed>
+
+<bibliomixed id="infoset"><abbrev>XML Infoset</abbrev>John Cowan, Richard Tobin,
+editors.
+<citetitle><ulink url="http://www.w3.org/TR/xml-infoset/">XML
+Information Set</ulink></citetitle>.
+W3C (World Wide Web Consortium), 2001.</bibliomixed>
+
+<bibliomixed id="rfc2396"><abbrev>RFC 2396</abbrev>T. Berners-Lee, R. Fielding, L. Masinter.
+<citetitle><ulink url="http://www.ietf.org/rfc/rfc2396.txt" >RFC 2396:
+Uniform Resource Identifiers (URI): Generic
+Syntax</ulink></citetitle>.
+IETF (Internet Engineering Task Force). 1998.</bibliomixed>
+
+<bibliomixed id="rfc2732"><abbrev>RFC 2732</abbrev>R. Hinden, B. Carpenter, L. Masinter.
+<citetitle><ulink url="http://www.ietf.org/rfc/rfc2732.txt">RFC 2732: Format for Literal IPv6 Addresses in URL's</ulink></citetitle>.
+IETF (Internet Engineering Task Force), 1999.</bibliomixed>
+
+<bibliomixed id="rfc3023"><abbrev>RFC 3023</abbrev> M. Murata,
+S. St.Laurent, D. Kohn. <citetitle><ulink
+url="http://www.ietf.org/rfc/rfc3023.txt">RFC 3023: XML Media
+Types</ulink></citetitle>. IETF (Internet Engineering Task Force),
+2001.</bibliomixed>
+
+</bibliodiv>
+
+<bibliodiv><title>Non-Normative</title>
+
+<bibliomixed id="xmlschema-2"><abbrev>W3C XML Schema Datatypes</abbrev>Paul V. Biron, Ashok Malhotra, editors.
+<citetitle><ulink url="http://www.w3.org/TR/xmlschema-2/">XML Schema Part 2: Datatypes</ulink></citetitle>.
+W3C (World Wide Web Consortium), 2001.</bibliomixed>
+
+<bibliomixed id="trex"><abbrev>TREX</abbrev>James Clark.
+<citetitle><ulink url="http://www.thaiopensource.com/trex/">TREX - Tree Regular Expressions for XML</ulink></citetitle>.
+Thai Open Source Software Center, 2001.</bibliomixed>
+
+<bibliomixed id="relax"><abbrev>RELAX</abbrev>MURATA Makoto.
+<citetitle><ulink url="http://www.xml.gr.jp/relax/">RELAX (Regular
+Language description for XML)</ulink></citetitle>. INSTAC
+(Information Technology Research and Standardization Center), 2001.</bibliomixed>
+
+<bibliomixed id="xsfd"><abbrev>XML Schema Formal</abbrev>Allen Brown,
+Matthew Fuchs, Jonathan Robie, Philip Wadler, editors.
+<citetitle><ulink url="http://www.w3.org/TR/xmlschema-formal/">XML Schema: Formal Description</ulink></citetitle>.
+W3C (World Wide Web Consortium), 2001.</bibliomixed>
+
+<bibliomixed id="tutorial"><abbrev>Tutorial</abbrev>James Clark,
+Makoto MURATA, editors. <citetitle><ulink
+url="http://www.oasis-open.org/committees/relax-ng/tutorial.html">RELAX
+NG Tutorial</ulink></citetitle>. OASIS, 2001.</bibliomixed>
+
+</bibliodiv>
+
+</bibliography>
+
+</article>
|