<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
  xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
  datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
  <start>
    <a:documentation>The root element can be any element that is not in a DeltaXML namespace. It
      contains the elements that are used to retain the: XML declaration; the DOCTYPE; and the
      comments and processing instructions that are outside the body in the specified order. Note
      that the original document elements are also included in this sequence.</a:documentation>
    <element>
      <anyName>
        <except>
          <nsName ns="http://www.deltaxml.com/ns/preserve"/>
          <nsName ns="http://www.deltaxml.com/ns/processing-instructions"/>
          <nsName ns="http://www.deltaxml.com/ns/entity-references"/>
          <nsName ns="http://www.deltaxml.com/ns/well-formed-delta-v1"/>
        </except>
      </anyName>
      <zeroOrMore>
        <attribute>
          <anyName/>
        </attribute>
      </zeroOrMore>
      <optional>
        <ref name="xmldecl"/>
      </optional>
      <optional>
        <ref name="pi-and-comment"/>
      </optional>
      <optional>
        <ref name="doctype"/>
      </optional>
      <optional>
        <ref name="pi-and-comment"/>
      </optional>
      <zeroOrMore>
        <ref name="body-element"/>
      </zeroOrMore>
      <optional>
        <ref name="pi-and-comment"/>
      </optional>
    </element>
  </start>

  <define name="xmldecl">
    <a:documentation>The XML declaration can be retained as a childless element, where the version
      and encoding data can be encoded in attributes. Note that the standalone attribute is not
      retained as this cannot currently be preserved.</a:documentation>
    <element name="xmldecl" ns="http://www.deltaxml.com/ns/preserve">
      <optional>
        <attribute name="version" ns="">
          <choice>
            <value>1.0</value>
            <value>1.1</value>
          </choice>
        </attribute>
      </optional>
      <optional>
        <attribute name="encoding" ns="">
          <text/>
        </attribute>
      </optional>
      <!--
      <optional>
        <attribute name="standalone" ns="">
          <choice>
            <value>no</value>
            <value>yes</value>
          </choice>
        </attribute>
      </optional>
      -->
      <empty/>
    </element>
  </define>

  <define name="external-ref">
    <a:documentation>External references can have public and system identifiers, which can be
      encoded into <code>publicId</code> and <code>systemId</code> attributes.</a:documentation>
    <optional>
      <optional>
        <attribute name="publicId" ns=""/>
      </optional>
      <attribute name="systemId" ns=""/>
    </optional>
  </define>

  <define name="doctype">
    <a:documentation>The DOCTYPE and its internal subset data can be retained in a
        <code>preserve:doctype</code> element, where: the <code>name</code> attribute is used to
      specify the root element's name; the optional external reference attributes are used to
      identify the element's DOCTYPE specification; and its child elements are used to retain the
      optional internal subset data.</a:documentation>
    <element name="doctype" ns="http://www.deltaxml.com/ns/preserve">
      <attribute name="name" ns=""/>
      <ref name="external-ref"/>
      <ref name="internal-subset"/>
    </element>
  </define>

  <define name="pi-and-comment">
    <a:documentation>The process instruction and comments block for retaining PIs and comments
      outside the body of the document. It can appear in one of three locations, before the DOCTYPE
      (or document body), between the DOCTYPE and document body, and after the document body. These
      regions are identified by the <code>BEFORE_DTD</code>, <code>AFTER_DTD</code>, and
        <code>AFTER_BODY</code> labels respectively.</a:documentation>
    <element name="pi-and-comment" ns="http://www.deltaxml.com/ns/preserve">
      <attribute name="region" ns="">
        <choice>
          <value>BEFORE_DTD</value>
          <value>AFTER_DTD</value>
          <value>AFTER_BODY</value>
        </choice>
      </attribute>
      <zeroOrMore>
        <interleave>
          <ref name="pi"/>
          <ref name="comment"/>
        </interleave>
      </zeroOrMore>
    </element>
  </define>

  <define name="pi">
    <a:documentation>A processing instruction can be retained by creating an element in the
        <code>http://www.deltaxml.com/ns/processing-instructions</code> namespace, where the element
      name is the same as the processing instructions tag, and the element content is the same as
      the processing instructions content.</a:documentation>
    <element>
      <nsName ns="http://www.deltaxml.com/ns/processing-instructions"/>
      <attribute name="xml:space">
        <value>preserve</value>
      </attribute>
      <text/>
    </element>
  </define>

  <define name="er">
    <a:documentation>An entity reference can be retained by creating an element in the
        <code>http://www.deltaxml.com/ns/entity-references</code> namespace, where the element name
      is the same as the entity's name, and the optional element content is the same as the entity's
      content (i.e. replacement text). Further, entity references within the internal subset can
      indicated that they are parameter references by setting the <code>parameter</code> attribute.
      Note that it is possible for the replacement text to contain entity
      references.</a:documentation>
    <element>
      <nsName ns="http://www.deltaxml.com/ns/entity-references"/>
      <optional>
        <attribute name="parameter" ns="">
          <choice>
            <value>no</value>
            <value>yes</value>
          </choice>
        </attribute>
      </optional>
      <mixed>
        <ref name="body-element"/>
      </mixed>
    </element>
  </define>

  <define name="comment">
    <a:documentation>A comment can be retained by enclosing its contents in a
        <code>preserve:comment</code> element.</a:documentation>
    <element name="comment" ns="http://www.deltaxml.com/ns/preserve">
      <attribute name="xml:space">
        <value>preserve</value>
      </attribute>
      <text/>
    </element>
  </define>

  <define name="cdata">
    <a:documentation>A CDATA section can be retained by enclosing its contents in a
        <code>preserve:cdata</code> element.</a:documentation>
    <element name="cdata" ns="http://www.deltaxml.com/ns/preserve">
      <text/>
    </element>
  </define>

  <define name="body-element" combine="choice">
    <a:documentation>A body element is any foreign element, DeltaXML deltaV2 (difference reporting)
      element, or a retained comment, processing instruction, cdata, or entity reference
      element.</a:documentation>
    <choice>
      <ref name="foreign-body-element"/>
      <ref name="deltaV2-element"/>
      <ref name="comment"/>
      <ref name="pi"/>
      <ref name="cdata"/>
      <ref name="er"/>
    </choice>
  </define>

  <define name="foreign-body-element">
    <a:documentation>A foreign body element is any element that is not in the DeltaXML namespace. It
      can contain any attributes and any body-element children.</a:documentation>
    <element>
      <anyName>
        <except>
          <nsName ns="http://www.deltaxml.com/ns/preserve"/>
          <nsName ns="http://www.deltaxml.com/ns/processing-instructions"/>
          <nsName ns="http://www.deltaxml.com/ns/entity-references"/>
          <nsName ns="http://www.deltaxml.com/ns/well-formed-delta-v1"/>
        </except>
      </anyName>
      <zeroOrMore>
        <attribute>
          <anyName/>
        </attribute>
      </zeroOrMore>
      <zeroOrMore>
        <ref name="body-element"/>
      </zeroOrMore>
    </element>
  </define>

  <define name="deltaV2-element">
    <a:documentation>A deltaV2 element is used to represent all the elements in the
        <code>http://www.deltaxml.com/ns/well-formed-delta-v1</code> namespace. These elements are
      used for recording the differences between the content of two (or more) deltaxml
      files.</a:documentation>
    <element>
      <nsName ns="http://www.deltaxml.com/ns/well-formed-delta-v1"/>
      <zeroOrMore>
        <attribute>
          <anyName/>
        </attribute>
      </zeroOrMore>
      <zeroOrMore>
        <choice>
          <ref name="deltaV2-element"/>
          <ref name="foreign-body-element"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>

  <define name="internal-subset">
    <a:documentation>A DOCTYPE's internal subset can contain element, attribute, notation, entity
      declaration, and entity reference elements (in addition to comments and processing
      instructions which are currently not retained).</a:documentation>
    <choice>
      <ref name="elementDecl"/>
      <ref name="attributeDecl"/>
      <ref name="notationDecl"/>
      <ref name="internalParsedParameterEntityDecl"/>
      <ref name="internalParsedGeneralEntityDecl"/>
      <ref name="externalParsedParameterEntityDecl"/>
      <ref name="externalParsedGeneralEntityDecl"/>
      <ref name="unparsedEntityDecl"/>
      <ref name="er"/>
    </choice>
  </define>

  <define name="common-decl">
    <a:documentation>All the internal subset declarations have a name of thing being declared, and a
      DeltaXML key to ensure that this thing only matches with another element of the same type and
      name.</a:documentation>
    <attribute name="name" ns=""/>
    <attribute name="key" ns="http://www.deltaxml.com/ns/well-formed-delta-v1"/>
  </define>

  <define name="elementDecl">
    <a:documentation>An element declaration can be retained in a <code>preserve:elementDecl</code>
      element whose child content model as an attribute.</a:documentation>
    <element name="elementDecl" ns="http://www.deltaxml.com/ns/preserve">
      <ref name="common-decl"/>
      <attribute name="model" ns=""/>
    </element>
  </define>

  <define name="attributeDecl">
    <a:documentation>An attribute declaration can be retained in a
        <code>preserve:attributeDecl</code> element that uses attributes to record the associated
      element name, attribute type, and optionally default value.</a:documentation>
    <element name="attributeDecl" ns="http://www.deltaxml.com/ns/preserve">
      <ref name="common-decl"/>
      <attribute name="ename"/>
      <attribute name="type"/>
      <optional>
        <attribute name="value"/>
      </optional>
    </element>
  </define>

  <define name="notationDecl">
    <a:documentation>A notation declaration can be retained in a <code>preserve:notationDecl</code>
      element.</a:documentation>
    <element name="notationDecl" ns="http://www.deltaxml.com/ns/preserve">
      <ref name="common-decl"/>
      <ref name="external-ref"/>
    </element>
  </define>

  <define name="internalParsedParameterEntityDecl">
    <a:documentation>An internal parsed parameter entity declaration can be retained in a
        <code>preserve:internalParsedParameterEntityDecl</code> element, where its value is recorded
      in a <code>value</code> attribute. Note that entities within the value are encoded as
      discussed in the Lexical Preservation Format documentation.</a:documentation>
    <element name="internalParsedParameterEntityDecl">
      <ref name="common-decl"/>
      <attribute name="value"/>
    </element>
  </define>

  <define name="internalParsedGeneralEntityDecl">
    <a:documentation>An internal parsed general entity declaration can be retained in a
        <code>preserve:internalParsedGeneralEntityDecl</code> element, where its value is recorded
      in a <code>value</code> attribute.  Note that entities within the value are encoded as
      discussed in the Lexical Preservation Format documentation.</a:documentation>
    <element name="internalParsedGeneralEntityDecl">
      <ref name="common-decl"/>
      <attribute name="value"/>
    </element>
  </define>

  <define name="externalParsedParameterEntityDecl">
    <a:documentation>An external parsed parameter entity declaration can be retained in a
        <code>preserve:externalParsedParameterEntityDecl</code> element.</a:documentation>
    <element name="externalParsedParameterEntityDecl">
      <ref name="common-decl"/>
      <ref name="external-ref"/>
    </element>
  </define>

  <define name="externalParsedGeneralEntityDecl">
    <a:documentation>An external parsed general entity declaration can be retained in a
        <code>preserve:externalParsedGeneralEntityDecl</code> element.</a:documentation>
    <element name="externalParsedGeneralEntityDecl">
      <ref name="common-decl"/>
      <ref name="external-ref"/>
    </element>
  </define>

  <define name="unparsedEntityDecl">
    <a:documentation>An unparsed entity declaration can be retained in a
        <code>preserve:unparsedEntityDecl</code> element, whose optional notation name is contained
      in a <code>notationName</code> attribute.</a:documentation>
    <element name="unparsedEntityDecl">
      <ref name="common-decl"/>
      <ref name="external-ref"/>
      <optional>
        <attribute name="notationName"/>
      </optional>
    </element>
  </define>

</grammar>
