<?xml version="1.0"?>
<!-- RELAX NG for RELAX NG -->
<grammar datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
         ns="http://relaxng.org/ns/structure/1.0"
         xmlns="http://relaxng.org/ns/structure/1.0">
  <start>
    <ref name="pattern"/>
  </start>

  <define name="pattern">
    <choice>
      <element name="element">
        <choice>
          <attribute name="name">
            <data type="QName"/>
          </attribute>
          <ref name="open-name-class"/>
        </choice>
        <ref name="common-atts"/>
        <ref name="open-patterns"/>
      </element>
      <element name="attribute">
        <ref name="common-atts"/>
        <choice>
	  <attribute name="name">
	    <data type="QName"/>
	  </attribute>
          <ref name="open-name-class"/>
        </choice>
        <interleave>
          <ref name="other"/>
          <optional>
            <ref name="pattern"/>
          </optional>
        </interleave>
      </element>
      <element name="group">
        <ref name="common-atts"/>
        <ref name="open-patterns"/>
      </element>
      <element name="interleave">
        <ref name="common-atts"/>
        <ref name="open-patterns"/>
      </element>
      <element name="choice">
        <ref name="common-atts"/>
        <ref name="open-patterns"/>
      </element>
      <element name="optional">
        <ref name="common-atts"/>
        <ref name="open-patterns"/>
      </element>
      <element name="zeroOrMore">
        <ref name="common-atts"/>
        <ref name="open-patterns"/>
      </element>
      <element name="oneOrMore">
        <ref name="common-atts"/>
        <ref name="open-patterns"/>
      </element>
      <element name="list">
        <ref name="common-atts"/>
        <ref name="open-patterns"/>
      </element>
      <element name="mixed">
        <ref name="common-atts"/>
        <ref name="open-patterns"/>
      </element>
      <element name="ref">
        <attribute name="name">
          <data type="NCName"/>
        </attribute>
        <ref name="common-atts"/>
        <ref name="other"/>
      </element>
      <element name="parentRef">
        <attribute name="name">
          <data type="NCName"/>
        </attribute>
        <ref name="common-atts"/>
        <ref name="other"/>
      </element>
      <element name="empty">
        <ref name="common-atts"/>
        <ref name="other"/>
      </element>
      <element name="text">
        <ref name="common-atts"/>
        <ref name="other"/>
      </element>
      <element name="value">
        <optional>
          <attribute name="type">
            <data type="NCName"/>
          </attribute>
        </optional>
        <ref name="common-atts"/>
        <text/>
      </element>
      <element name="data">
        <attribute name="type">
          <data type="NCName"/>
        </attribute>
        <ref name="common-atts"/>
        <interleave>
          <ref name="other"/>
          <group>
	    <zeroOrMore>
	      <element name="param">
		<attribute name="name">
		  <data type="NCName"/>
		</attribute>
                <ref name="common-atts"/>
		<text/>
	      </element>
	    </zeroOrMore>
            <optional>
              <element name="except">
		<ref name="common-atts"/>
		<ref name="open-patterns"/>
              </element>
            </optional>
          </group>
        </interleave>
      </element>
      <element name="notAllowed">
        <ref name="common-atts"/>
        <ref name="other"/>
      </element>
      <element name="externalRef">
        <attribute name="href">
          <data type="anyURI"/>
        </attribute>
        <ref name="common-atts"/>
        <ref name="other"/>
      </element>
      <element name="grammar">
        <ref name="common-atts"/>
        <ref name="grammar-content"/>
      </element>
    </choice>
  </define>

  <define name="grammar-content">
    <interleave>
      <ref name="other"/>
      <zeroOrMore>
        <choice>
          <ref name="start-element"/>
          <ref name="define-element"/>
          <element name="div">
            <ref name="common-atts"/>
            <ref name="grammar-content"/>
          </element>
          <element name="include">
            <attribute name="href">
              <data type="anyURI"/>
            </attribute>
            <ref name="common-atts"/>
            <ref name="include-content"/>
          </element>
        </choice>
      </zeroOrMore>
    </interleave>
  </define>

  <define name="include-content">
    <interleave>
      <ref name="other"/>
      <zeroOrMore>
        <choice>
          <ref name="start-element"/>
          <ref name="define-element"/>
          <element name="div">
            <ref name="common-atts"/>
            <ref name="include-content"/>
          </element>
        </choice>
      </zeroOrMore>
    </interleave>
  </define>

  <define name="start-element">
    <element name="start">
      <ref name="combine-att"/>
      <ref name="common-atts"/>
      <ref name="open-pattern"/>
    </element>
  </define>

  <define name="define-element">
    <element name="define">
      <attribute name="name">
        <data type="NCName"/>
      </attribute>
      <ref name="combine-att"/>
      <ref name="common-atts"/>
      <ref name="open-patterns"/>
    </element>
  </define>

  <define name="combine-att">
    <optional>
      <attribute name="combine">
        <choice>
          <value>choice</value>
          <value>interleave</value>
        </choice>
      </attribute>
    </optional>
  </define>
  
  <define name="open-patterns">
    <interleave>
      <ref name="other"/>
      <oneOrMore>
        <ref name="pattern"/>
      </oneOrMore>
    </interleave>
  </define>

  <define name="open-pattern">
    <interleave>
      <ref name="other"/>
      <ref name="pattern"/>
    </interleave>
  </define>

  <define name="name-class">
    <choice>
      <element name="name">
        <ref name="common-atts"/>
        <data type="QName"/>
      </element>
      <element name="anyName">
        <ref name="common-atts"/>
        <ref name="except-name-class"/>
      </element>
      <element name="nsName">
        <ref name="common-atts"/>
        <ref name="except-name-class"/>
      </element>
      <element name="choice">
        <ref name="common-atts"/>
        <ref name="open-name-classes"/>
      </element>
    </choice>
  </define>

  <define name="except-name-class">
    <interleave>
      <ref name="other"/>
      <optional>
        <element name="except">
          <ref name="open-name-classes"/>
        </element>
      </optional>
    </interleave>
  </define>

  <define name="open-name-classes">
    <interleave>
      <ref name="other"/>
      <oneOrMore>
        <ref name="name-class"/>
      </oneOrMore>
    </interleave>
  </define>

  <define name="open-name-class">
    <interleave>
      <ref name="other"/>
      <ref name="name-class"/>
    </interleave>
  </define>

  <define name="common-atts">
    <optional>
      <attribute name="ns"/>
    </optional>
    <optional>
      <attribute name="datatypeLibrary">
        <data type="anyURI"/>
      </attribute>
    </optional>
    <zeroOrMore>
      <attribute>
        <anyName>
          <except>
            <nsName/>
            <nsName ns=""/>
          </except>
        </anyName>
      </attribute>
    </zeroOrMore>
  </define>

  <define name="other">
    <zeroOrMore>
      <element>
        <anyName>
          <except>
            <nsName/>
          </except>
        </anyName>
        <zeroOrMore>
          <choice>
            <attribute>
              <anyName/>
            </attribute>
            <text/>
            <ref name="any"/>
          </choice>
        </zeroOrMore>
      </element>
    </zeroOrMore>
  </define>

  <define name="any">
    <element>
      <anyName/>
      <zeroOrMore>
        <choice>
          <attribute>
            <anyName/>
          </attribute>
          <text/>
          <ref name="any"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>

</grammar>
