<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE schema PUBLIC "-//W3C//DTD XMLSchema 200102//EN" "http://www.w3.org/2001/XMLSchema.dtd">
<schema xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
        targetNamespace="http://www.w3.org/1999/02/22-rdf-syntax-ns#">

  <annotation>
    <documentation xml:lang="en">

      Based on
        http://www.w3.org/2000/07/rdf.xsd 
        derived by Ralph Swick
      from
        http://www.oasis-open.org/cover/xmlSchemaForRDF.html
        originally
        http://lists.xml.org/archives/xml-dev/200002/msg00618.html
        by Rick Jelliffe
 
    </documentation>
 </annotation>


  <!-- Top-level of RDF Document -->
  <element name="RDF">
    <complexType>
      <sequence maxOccurs="unbounded">
        <group ref="rdf:obj"/> <!-- abstract -->
      </sequence>
    </complexType>
  </element>

  <group name="obj">
    <choice>
      <element ref="rdf:typedNode"/>
    </choice>
  </group>

  <!-- @@check this after doing typednode -->
  <element name="Description"
           type="rdf:typedNodeType" equivClass="rdf:typedNode" />


  <attributeGroup name="idAboutAttrOpt">
    <annotation><documentation source="http://www.w3.org/TR/1999/REC-rdf-syntax-19990222/#aboutAttr"/></annotation>
    <attributeGroup ref="rdf:aboutAttrOpt"/>
    <attributeGroup ref="rdf:idAttrOpt"/>

  </attributeGroup>

  <attribute name="ID" type="ID" />

  <attributeGroup name="idAttrOpt">
    <attribute ref="rdf:ID" use='optional'/>
  </attributeGroup>

  <attribute name="about" type="uriReference" />
  <attributeGroup name="aboutAttrOpt">
    <attribute ref="rdf:about" use='optional' />
  </attributeGroup>

  <!-- leaving out bagIdAttr @@-->

  <!-- leaving out propAttr @@-->

  <!-- leaving out typeAttr @@-->

  <element name="propertyElt" abstract="true"
           type="rdf:propertyEltType" />

  <complexType name="propertyEltType">
    <complexContent>
      <restriction base="rdf:item">
        <annotation><documentation>this is a "union type"; use
        xsi:type in the instance to discriminate between concrete subtypes
        </documentation></annotation>
      </restriction>
    </complexContent>
  </complexType>

  <complexType name="propertyEltValue" content="textOnly">
    <complexContent>
      <restriction base="rdf:propertyEltType">
        <attributeGroup ref="rdf:idAttrOpt"/>
      </restriction>
    </complexContent>
  </complexType>

  <complexType name="propertyEltLiteral" content="mixed">
    <complexContent>
      <restriction base="rdf:propertyEltType">
	<any minOccurs="0" processContents="skip"/>
	<attributeGroup ref="rdf:idAttrOpt"/>
	<attributeGroup ref="rdf:parseLiteral"/>
      </restriction>
    </complexContent>
  </complexType>

  <complexType name="propertyEltResource">
    <complexContent>
      <restriction base="rdf:propertyEltType">
	<sequence maxOccurs="unbounded">
	  <element ref="rdf:propertyElt"   /><!--abstract !-->
	</sequence>
      </restriction>
    </complexContent>
  </complexType>

  <complexType name="propertyEltRef" content="empty">
    <complexContent>
      <restriction base="rdf:propertyEltType">
      <attributeGroup ref="rdf:idRefAttrOpt"/>
      <!-- @@leaving out bagIdAttr? -->
      <!-- @@leaving out propAttr* -->
      </restriction>
    </complexContent>
  </complexType>

  <element name="typedNode" abstract="true"
	   type="rdf:typedNodeType"/>

  <complexType name="typedNodeType">
    <sequence maxOccurs="unbounded">
      <element ref="rdf:propertyElt"/>
    </sequence>
    <attributeGroup ref="rdf:idAboutAttrOpt"/>
    <!--@@leaving out bagidattr, propattr -->
  </complexType>

  <attributeGroup name="idRefAttrOpt">
    <attributeGroup ref="rdf:idAttrOpt"/>
    <attributeGroup ref="rdf:resourceAttrOpt"/>
  </attributeGroup>

 <!--@@ can complex types be abstract? or just elements? -->
  <complexType name="value" abstract="true">
    <complexContent>
      <restriction base="rdf:propertyEltType"/>
    </complexContent>
  </complexType>

  <complexType name="valueObj">
    <complexContent>
      <restriction base="rdf:value">
        <group ref="rdf:obj"/>
      </restriction>
    </complexContent>
  </complexType>

  <complexType name="valueString" content="mixed">
    <complexContent>
      <restriction base="rdf:value">
        <sequence/> <!-- no subelements -->
      </restriction>
    </complexContent>
  </complexType>

  <attribute name="resource" type="uriReference" />

  <attributeGroup name="resourceAttrOpt">
    <attribute name="resource" use='optional' type="uriReference" />
    <attribute ref="rdf:resource" use='optional' />
  </attributeGroup>

  <attributeGroup name="resourceAttr">
    <!-- @@er... which one to require? -->
    <attribute name="resource" use='optional' type="uriReference" />
    <attribute ref="rdf:resource" use='optional' />
  </attributeGroup>

  <element name="Seq" type="rdf:members"/>
  <element name="Bag" type="rdf:members"/>
  <element name="Alt" type="rdf:members"/>
  <!-- @@restrict Alt to have at least one member -->

  <complexType name="members">
    <sequence maxOccurs="unbounded">
      <element name="li" type="rdf:item"/>
    </sequence>
    <attributeGroup ref="rdf:idAttrOpt"/>
    <!-- @@leaving out memberAttr* -->
  </complexType>

  <complexType name="item">
    <annotation><documentation>this is a "union type"; use
    xsi:type in the instance to discriminate between concrete subtypes.
    @@hmm... can I mark this as "abstract" somehow?
    </documentation></annotation>
  </complexType>

  <complexType name="referencedItem" content="empty">
    <complexContent>
      <restriction base="rdf:item">
        <attributeGroup ref="rdf:resourceAttr"/>
      </restriction>
    </complexContent>
  </complexType>

  <!-- @@strictly speaking, inlineItem should be
       specified as subtypes, one of propertyEltValue,
       propertyEltLiteral, and propertyEltResource,
       with use="prohibited" on some attributes to
       get rid of them. But I'm gonna skip it for now -->

  <attribute name="parseType"/>
  <attributeGroup name="parseLiteral">
    <attribute ref="rdf:parseType" use='required' fixed="Literal" />
  </attributeGroup>

  <attributeGroup name="parseResource">
    <attribute ref="rdf:parseType"  use='required' fixed="Resource" />
  </attributeGroup>

  <!-- so much for syntax structure. Now for the particular
       properties and classes... -->

  <element name="Statement"
	   type="rdf:typedNodeType" equivClass="rdf:typedNode" />

  <element name="Property"
           type="rdf:typedNodeType" equivClass="rdf:typedNode" />

	   <!-- these are is constrained to use resource="...";
		use xsi:type to do something else -->
  <element name="subject"
	   type="rdf:propertyEltRef" equivClass="rdf:propertyElt" />

  <element name="predicate"
	   type="rdf:propertyEltRef" equivClass="rdf:propertyElt" />

  <element name="object"
	   type="rdf:propertyEltRef" equivClass="rdf:propertyElt" />

  <element name="type"
	   type="rdf:propertyEltRef" equivClass="rdf:propertyElt" />

  <!-- constrained to the <value>...</value> syntax -->
  <element name="value"
	   type="rdf:valueString" equivClass="rdf:propertyElt" />

</schema>

