<?xml version="1.0" encoding="UTF-8"?>
<!--
  
  RELAX NG Compact Schema for RDF/XML Syntax
  
  This schema is for information only and NON-NORMATIVE
  
  It is based on one originally written by James Clark in
  http://lists.w3.org/Archives/Public/www-rdf-comments/2001JulSep/0248.html
  and updated with later changes.
  
-->
<grammar xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ns="http://www.w3.org/XML/1998/namespace" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
  <start>
    <ref name="doc"/>
  </start>
  <!-- I cannot seem to do this in RNGC so they are expanded in-line -->
  <!--
    coreSyntaxTerms = rdf:RDF | rdf:ID | rdf:about | rdf:parseType | rdf:resource | rdf:nodeID | rdf:datatype
    syntaxTerms = coreSyntaxTerms | rdf:Description | rdf:li
    oldTerms    = rdf:aboutEach | rdf:aboutEachPrefix | rdf:bagID
    nodeElementURIs       = * - ( coreSyntaxTerms | rdf:li | oldTerms )
    propertyElementURIs   = * - ( coreSyntaxTerms | rdf:Description | oldTerms )
    propertyAttributeURIs = * - ( coreSyntaxTerms | rdf:Description | rdf:li | oldTerms )
  -->
  <!--
    Also needed to allow rdf:li on all property element productions
    since we can't capture the rdf:li rewriting to rdf_<n> in relaxng
  -->
  <!-- Need to add these explicitly -->
  <define name="xmllang">
    <attribute name="xml:lang"/>
  </define>
  <define name="xmlbase">
    <attribute name="xml:base"/>
  </define>
  <!-- and to forbid every other xml:* attribute, element -->
  <define name="doc">
    <ref name="RDF"/>
  </define>
  <define name="RDF">
    <element name="rdf:RDF">
      <optional>
        <ref name="xmllang"/>
      </optional>
      <optional>
        <ref name="xmlbase"/>
      </optional>
      <ref name="nodeElementList"/>
    </element>
  </define>
  <define name="nodeElementList">
    <zeroOrMore>
      <ref name="nodeElement"/>
    </zeroOrMore>
  </define>
  <!--
    Should be something like:
     ws* , (  nodeElement , ws* )*
    but RELAXNG does this by default, ignoring whitespace separating tags.
  -->
  <define name="nodeElement">
    <element>
      <anyName>
        <except>
          <nsName ns=""/>
          <name>rdf:RDF</name>
          <name>rdf:ID</name>
          <name>rdf:about</name>
          <name>rdf:parseType</name>
          <name>rdf:resource</name>
          <name>rdf:nodeID</name>
          <name>rdf:datatype</name>
          <name>rdf:li</name>
          <name>rdf:aboutEach</name>
          <name>rdf:aboutEachPrefix</name>
          <name>rdf:bagID</name>
        </except>
      </anyName>
      <optional>
        <choice>
          <ref name="idAttr"/>
          <ref name="nodeIdAttr"/>
          <ref name="aboutAttr"/>
        </choice>
      </optional>
      <optional>
        <ref name="xmllang"/>
      </optional>
      <optional>
        <ref name="xmlbase"/>
      </optional>
      <zeroOrMore>
        <ref name="propertyAttr"/>
      </zeroOrMore>
      <ref name="propertyEltList"/>
    </element>
  </define>
  <!--
    It is not possible to say "and not things
    beginning with _ in the rdf: namespace" in RELAX NG.
  -->
  <define name="ws">
    <value> </value>
  </define>
  <!--
    Not used in this RELAX NG schema; but should be any legal XML
    whitespace defined by http://www.w3.org/TR/2000/REC-xml-20001006#NT-S
  -->
  <define name="propertyEltList">
    <zeroOrMore>
      <ref name="propertyElt"/>
    </zeroOrMore>
  </define>
  <!--
    Should be something like:
     ws* , ( propertyElt , ws* )*
    but RELAXNG does this by default, ignoring whitespace separating tags.
  -->
  <define name="propertyElt">
    <choice>
      <ref name="resourcePropertyElt"/>
      <ref name="literalPropertyElt"/>
      <ref name="parseTypeLiteralPropertyElt"/>
      <ref name="parseTypeResourcePropertyElt"/>
      <ref name="parseTypeCollectionPropertyElt"/>
      <ref name="parseTypeOtherPropertyElt"/>
      <ref name="emptyPropertyElt"/>
    </choice>
  </define>
  <define name="resourcePropertyElt">
    <element>
      <anyName>
        <except>
          <nsName ns=""/>
          <name>rdf:RDF</name>
          <name>rdf:ID</name>
          <name>rdf:about</name>
          <name>rdf:parseType</name>
          <name>rdf:resource</name>
          <name>rdf:nodeID</name>
          <name>rdf:datatype</name>
          <name>rdf:Description</name>
          <name>rdf:aboutEach</name>
          <name>rdf:aboutEachPrefix</name>
          <name>rdf:bagID</name>
          <nsName/>
        </except>
      </anyName>
      <optional>
        <ref name="idAttr"/>
      </optional>
      <optional>
        <ref name="xmllang"/>
      </optional>
      <optional>
        <ref name="xmlbase"/>
      </optional>
      <ref name="nodeElement"/>
    </element>
  </define>
  <define name="literalPropertyElt">
    <element>
      <anyName>
        <except>
          <nsName ns=""/>
          <name>rdf:RDF</name>
          <name>rdf:ID</name>
          <name>rdf:about</name>
          <name>rdf:parseType</name>
          <name>rdf:resource</name>
          <name>rdf:nodeID</name>
          <name>rdf:datatype</name>
          <name>rdf:Description</name>
          <name>rdf:aboutEach</name>
          <name>rdf:aboutEachPrefix</name>
          <name>rdf:bagID</name>
          <nsName/>
        </except>
      </anyName>
      <optional>
        <choice>
          <ref name="idAttr"/>
          <ref name="datatypeAttr"/>
        </choice>
      </optional>
      <optional>
        <ref name="xmllang"/>
      </optional>
      <optional>
        <ref name="xmlbase"/>
      </optional>
      <text/>
    </element>
  </define>
  <define name="parseTypeLiteralPropertyElt">
    <element>
      <anyName>
        <except>
          <nsName ns=""/>
          <name>rdf:RDF</name>
          <name>rdf:ID</name>
          <name>rdf:about</name>
          <name>rdf:parseType</name>
          <name>rdf:resource</name>
          <name>rdf:nodeID</name>
          <name>rdf:datatype</name>
          <name>rdf:Description</name>
          <name>rdf:aboutEach</name>
          <name>rdf:aboutEachPrefix</name>
          <name>rdf:bagID</name>
          <nsName/>
        </except>
      </anyName>
      <optional>
        <ref name="idAttr"/>
      </optional>
      <ref name="parseLiteral"/>
      <optional>
        <ref name="xmllang"/>
      </optional>
      <optional>
        <ref name="xmlbase"/>
      </optional>
      <ref name="literal"/>
    </element>
  </define>
  <define name="parseTypeResourcePropertyElt">
    <element>
      <anyName>
        <except>
          <nsName ns=""/>
          <name>rdf:RDF</name>
          <name>rdf:ID</name>
          <name>rdf:about</name>
          <name>rdf:parseType</name>
          <name>rdf:resource</name>
          <name>rdf:nodeID</name>
          <name>rdf:datatype</name>
          <name>rdf:Description</name>
          <name>rdf:aboutEach</name>
          <name>rdf:aboutEachPrefix</name>
          <name>rdf:bagID</name>
          <nsName/>
        </except>
      </anyName>
      <optional>
        <ref name="idAttr"/>
      </optional>
      <ref name="parseResource"/>
      <optional>
        <ref name="xmllang"/>
      </optional>
      <optional>
        <ref name="xmlbase"/>
      </optional>
      <ref name="propertyEltList"/>
    </element>
  </define>
  <define name="parseTypeCollectionPropertyElt">
    <element>
      <anyName>
        <except>
          <nsName ns=""/>
          <name>rdf:RDF</name>
          <name>rdf:ID</name>
          <name>rdf:about</name>
          <name>rdf:parseType</name>
          <name>rdf:resource</name>
          <name>rdf:nodeID</name>
          <name>rdf:datatype</name>
          <name>rdf:Description</name>
          <name>rdf:aboutEach</name>
          <name>rdf:aboutEachPrefix</name>
          <name>rdf:bagID</name>
          <nsName/>
        </except>
      </anyName>
      <optional>
        <ref name="idAttr"/>
      </optional>
      <optional>
        <ref name="xmllang"/>
      </optional>
      <optional>
        <ref name="xmlbase"/>
      </optional>
      <ref name="parseCollection"/>
      <ref name="nodeElementList"/>
    </element>
  </define>
  <define name="parseTypeOtherPropertyElt">
    <element>
      <anyName>
        <except>
          <nsName ns=""/>
          <name>rdf:RDF</name>
          <name>rdf:ID</name>
          <name>rdf:about</name>
          <name>rdf:parseType</name>
          <name>rdf:resource</name>
          <name>rdf:nodeID</name>
          <name>rdf:datatype</name>
          <name>rdf:Description</name>
          <name>rdf:aboutEach</name>
          <name>rdf:aboutEachPrefix</name>
          <name>rdf:bagID</name>
          <nsName/>
        </except>
      </anyName>
      <optional>
        <ref name="idAttr"/>
      </optional>
      <optional>
        <ref name="xmllang"/>
      </optional>
      <optional>
        <ref name="xmlbase"/>
      </optional>
      <ref name="parseOther"/>
      <ref name="any"/>
    </element>
  </define>
  <define name="emptyPropertyElt">
    <element>
      <anyName>
        <except>
          <nsName ns=""/>
          <name>rdf:RDF</name>
          <name>rdf:ID</name>
          <name>rdf:about</name>
          <name>rdf:parseType</name>
          <name>rdf:resource</name>
          <name>rdf:nodeID</name>
          <name>rdf:datatype</name>
          <name>rdf:Description</name>
          <name>rdf:aboutEach</name>
          <name>rdf:aboutEachPrefix</name>
          <name>rdf:bagID</name>
          <nsName/>
        </except>
      </anyName>
      <optional>
        <ref name="idAttr"/>
      </optional>
      <optional>
        <choice>
          <ref name="resourceAttr"/>
          <ref name="nodeIdAttr"/>
        </choice>
      </optional>
      <optional>
        <ref name="xmllang"/>
      </optional>
      <optional>
        <ref name="xmlbase"/>
      </optional>
      <zeroOrMore>
        <ref name="propertyAttr"/>
      </zeroOrMore>
    </element>
  </define>
  <define name="idAttr">
    <attribute name="rdf:ID">
      <ref name="IDsymbol"/>
    </attribute>
  </define>
  <define name="nodeIdAttr">
    <attribute name="rdf:nodeID">
      <ref name="IDsymbol"/>
    </attribute>
  </define>
  <define name="aboutAttr">
    <attribute name="rdf:about">
      <ref name="URI-reference"/>
    </attribute>
  </define>
  <define name="propertyAttr">
    <attribute>
      <anyName>
        <except>
          <nsName ns=""/>
          <name>rdf:RDF</name>
          <name>rdf:ID</name>
          <name>rdf:about</name>
          <name>rdf:parseType</name>
          <name>rdf:resource</name>
          <name>rdf:nodeID</name>
          <name>rdf:datatype</name>
          <name>rdf:li</name>
          <name>rdf:Description</name>
          <name>rdf:aboutEach</name>
          <name>rdf:aboutEachPrefix</name>
          <name>rdf:bagID</name>
          <nsName/>
        </except>
      </anyName>
      <data type="string" datatypeLibrary=""/>
    </attribute>
  </define>
  <define name="resourceAttr">
    <attribute name="rdf:resource">
      <ref name="URI-reference"/>
    </attribute>
  </define>
  <define name="datatypeAttr">
    <attribute name="rdf:datatype">
      <ref name="URI-reference"/>
    </attribute>
  </define>
  <define name="parseLiteral">
    <attribute name="rdf:parseType">
      <value>Literal</value>
    </attribute>
  </define>
  <define name="parseResource">
    <attribute name="rdf:parseType">
      <value>Resource</value>
    </attribute>
  </define>
  <define name="parseCollection">
    <attribute name="rdf:parseType">
      <value>Collection</value>
    </attribute>
  </define>
  <define name="parseOther">
    <attribute name="rdf:parseType"/>
  </define>
  <define name="URI-reference">
    <data type="string" datatypeLibrary=""/>
  </define>
  <define name="literal">
    <ref name="any"/>
  </define>
  <define name="IDsymbol">
    <data type="NMTOKEN"/>
  </define>
  <define name="any">
    <mixed>
      <zeroOrMore>
        <element>
          <anyName/>
          <zeroOrMore>
            <attribute>
              <anyName/>
            </attribute>
          </zeroOrMore>
          <ref name="any"/>
        </element>
      </zeroOrMore>
    </mixed>
  </define>
</grammar>
