| <?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_0.xml,v 1.1.1.1 2012/03/29 17:21:26 uid42307 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_0.xml,v 1.1.1.1 2012/03/29 17:21:26 uid42307 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> |