<?xml version='1.0' encoding='UTF-8' ?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
  xmlns:o="http://www.o-xml.org/lang/"
  targetNamespace="http://www.o-xml.org/lang/">

  <import schemaLocation="http://www.o-xml.org/namespace/document/"
	  namespace="http://www.o-xml.org/namespace/document/"/>

  <!-- meta -->
  <element name="meta" type="o:Meta"/>
  <complexType name="Meta" mixed="true">
    <attribute name="language" type="string" use="optional"/>
  </complexType>

  <!-- eval -->
  <element name="eval" type="o:Eval"/>
  <complexType name="Eval" >
    <attribute name="select" type="o:Expression" use="required"/>
  </complexType>

  <!-- do -->
  <element name="do" type="o:Do" />
  <complexType name="Do" mixed="true">
    <complexContent>
      <extension base="o:Container" >
        <attribute name="select" type="o:Expression" use="optional"/>
      </extension>
    </complexContent>
  </complexType>

  <!-- for-each -->
  <element name="for-each" type="o:ForEach"/>
  <complexType name="ForEach" mixed="true">
    <complexContent>
      <extension base="o:Container">
        <attributeGroup ref="o:for-each-nodeset"/>
        <attributeGroup ref="o:for-each-text"/>
        <attributeGroup ref="o:for-each-numeric"/>
      </extension>
    </complexContent>
  </complexType>

  <attributeGroup name="for-each-nodeset">
    <attribute name="select" type="o:Expression" use="optional"/>
  </attributeGroup>

  <attributeGroup name="for-each-text">
    <attribute name="in" type="o:Expression" use="optional"/>
    <attribute name="delim" type="string" default=" " use="optional"/>
  </attributeGroup>

  <attributeGroup name="for-each-numeric">
    <attribute name="from" type="decimal" default="0" use="optional"/>
    <attribute name="to" type="decimal" use="optional"/>
    <attribute name="step" type="decimal" default="1" use="optional"/>
  </attributeGroup>

  <!-- program -->
  <element name="program" type="o:Program"/>
  <complexType name="Program">
    <complexContent>
      <extension base="o:Container">
	<sequence>
	  <element ref="o:param" minOccurs="0" maxOccurs="unbounded"/>
	  <element ref="o:import" minOccurs="0" maxOccurs="unbounded"/>
	  <group ref="o:instructions" minOccurs="0" maxOccurs="unbounded"/>
	</sequence>
	<attribute name="space" type="string" default="ignore" use="optional"/>
	<attribute name="comments" type="string" default="ignore" use="optional"/>
	<attribute name="content-type" type="string" default="text/xml" use="optional"/>
      </extension>
    </complexContent>
  </complexType>

  <!-- log -->
  <element name="log" type="o:Log"/>
  <complexType name="Log" mixed="true">
    <complexContent>
      <extension base="o:Container">
        <attribute name="msg" type="o:MixedExpression" use="optional"/>
        <attribute name="select" type="o:Expression" use="optional"/>
      </extension>
    </complexContent>
  </complexType>

  <!-- return -->
  <element name="return" type="o:Return"/>
  <complexType name="Return" mixed="true">
    <complexContent>
      <extension base="o:Container">
        <attribute name="select" type="o:Expression" use="optional"/>
      </extension>
    </complexContent>
  </complexType>

  <!-- param -->
  <element name="param" type="o:Param"/>
  <complexType name="Param">
    <attribute name="name" type="o:QName" use="required"/>
    <attribute name="type" type="o:QName" use="optional" default="Node"/>
    <attribute name="select" type="o:Expression" use="optional"/>
  </complexType>

  <!-- parent -->
  <element name="parent" type="o:Parent"/>
  <complexType name="Parent">
    <attribute name="name" type="o:QName" use="required"/>
    <attribute name="type" type="o:QName" use="optional" default="Node"/>
    <attribute name="select" type="o:Expression" use="optional"/>
  </complexType>

  <!-- procedure -->
  <element name="procedure" type="o:Procedure"/>
  <complexType name="Procedure">
    <sequence>
      <element ref="o:param" minOccurs="0" maxOccurs="unbounded"/>
      <element ref="o:do" minOccurs="1" maxOccurs="1"/>
    </sequence>
    <attribute name="name" type="o:QName" use="required"/>
  </complexType>

  <!-- function -->
  <element name="function" type="o:Function"/>
  <complexType name="Function">
    <sequence>
      <element ref="o:param" minOccurs="0" maxOccurs="unbounded"/>
      <element ref="o:parent" minOccurs="0" maxOccurs="unbounded"/>
      <element ref="o:do" minOccurs="1" maxOccurs="1"/>
    </sequence>
    <attribute name="name" type="o:QName" use="required"/>
  </complexType>

  <!-- constructor -->
  <element name="constructor" type="o:Constructor"/>
  <complexType name="Constructor">
    <sequence>
      <element ref="o:param" minOccurs="0" maxOccurs="unbounded"/>
      <element ref="o:parent" minOccurs="0" maxOccurs="unbounded"/>
      <element ref="o:do" minOccurs="1" maxOccurs="1"/>
    </sequence>
  </complexType>

  <!-- type -->
  <element name="type" type="o:Type"/>
  <complexType name="Type">
    <sequence>
      <element ref="o:parent" minOccurs="0" maxOccurs="unbounded"/>
      <element ref="o:variable" minOccurs="0" maxOccurs="unbounded"/>
      <element ref="o:constructor" minOccurs="0" maxOccurs="unbounded"/>
      <element ref="o:function" minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
    <attribute name="name" type="o:QName" use="required"/>
  </complexType>

  <!-- variable -->
  <element name="variable" type="o:Variable"/>
  <complexType name="Variable" mixed="true">
    <complexContent>
      <extension base="o:Container">
        <attribute name="name" type="o:QName" use="required"/>
        <attribute name="select" type="o:Expression" use="optional"/>
      </extension>
    </complexContent>
  </complexType>

  <!-- set -->
  <element name="set" type="o:Set"/>
  <complexType name="Set">
    <anyAttribute namespace="##any" processContents="skip"/>
  </complexType>

  <!-- if -->
  <element name="if" type="o:SimpleConditional"/>

  <!-- while -->
  <element name="while" type="o:SimpleConditional"/>

  <complexType name="SimpleConditional" mixed="true">
    <complexContent>
      <extension base="o:Container">
        <attribute name="test" type="o:Expression" use="required"/>
      </extension>
    </complexContent>
  </complexType>

  <!-- choose -->
  <element name="choose" type="o:Choose"/>
  <complexType name="Choose">
    <sequence>
      <element ref="o:when" minOccurs="0" maxOccurs="unbounded"/>
      <element ref="o:otherwise" minOccurs="0" maxOccurs="1"/>
    </sequence>
  </complexType>
  <element name="when" type="o:SimpleConditional"/>
  <element name="otherwise" type="o:Container"/>

  <!-- import -->
  <element name="import" type="o:Import"/>
  <complexType name="Import">
    <attribute name="href" type="anyURI" use="required"/>
  </complexType>

  <!-- element -->
  <element name="element" type="o:Element"/>
  <complexType name="Element" mixed="true">
    <complexContent>
      <extension base="o:Container">
	<attribute name="name" type="o:MixedExpression" use="required"/>
	<attribute name="namespace" type="o:MixedExpression" use="optional"/>
      </extension>
    </complexContent>
  </complexType>

  <!-- attribute -->
  <element name="attribute" type="o:Attribute"/>
  <complexType name="Attribute" mixed="true">
    <complexContent>
      <extension base="o:Container">
	<attribute name="name" type="o:MixedExpression" use="required"/>
	<attribute name="namespace" type="o:MixedExpression" use="optional"/>
	<attribute name="select" type="o:Expression" use="optional"/>
	<attribute name="value" type="o:MixedExpression" use="optional"/>
      </extension>
    </complexContent>
  </complexType>

  <!-- text -->
  <element name="text" type="o:Text"/>
  <complexType name="Text" mixed="true">
    <complexContent>
      <extension base="o:Container">
	<attribute name="select" type="o:Expression" use="optional"/>
      </extension>
    </complexContent>
  </complexType>

  <!-- comment -->
  <element name="comment" type="o:Comment"/>
  <complexType name="Comment" mixed="true">
    <complexContent>
      <extension base="o:Container">
	<attribute name="select" type="o:Expression" use="optional"/>
      </extension>
    </complexContent>
  </complexType>

  <!-- document -->
  <element name="document" type="o:Document"/>
  <complexType name="Document">
    <complexContent>
      <extension base="o:Container">
	<!-- todo - standalone, charset etc -->
      </extension>
    </complexContent>
  </complexType>

  <!-- processing-instruction -->
  <element name="processing-instruction" type="o:ProcessingInstruction"/>
  <complexType name="ProcessingInstruction" mixed="true">
    <complexContent>
      <extension base="o:Container">
	<attribute name="target" type="o:MixedExpression" use="required"/>
	<attribute name="select" type="o:Expression" use="optional"/>
	<attribute name="value" type="o:MixedExpression" use="optional"/>
      </extension>
    </complexContent>
  </complexType>

  <!-- catch -->
  <element name="catch" type="o:Catch"/>
  <complexType name="Catch" mixed="true">
    <complexContent>
      <extension base="o:Container">
	<attribute name="handler" type="o:Expression" use="optional"/>
	<attribute name="exceptions" type="string" use="optional"/>
      </extension>
    </complexContent>
  </complexType>

  <!-- throw -->
  <element name="throw" type="o:Throw"/>
  <complexType name="Throw" mixed="true">
    <complexContent>
      <extension base="o:Container">
	<attribute name="select" type="o:Expression" use="optional"/>
      </extension>
    </complexContent>
  </complexType>

  <!-- assert -->
  <element name="assert" type="o:Assert"/>
  <complexType name="Assert">
    <attribute name="test" type="o:Expression" use="required"/>
    <attribute name="msg" type="o:MixedExpression" use="optional"/>
  </complexType>

  <!-- thread -->
  <element name="thread" type="o:Thread"/>
  <complexType name="Thread" mixed="true">
    <complexContent>
      <extension base="o:Container">
	<attribute name="priority" type="o:Expression" use="optional"/>
	<attribute name="daemon" type="o:MixedExpression" use="optional"/>
      </extension>
    </complexContent>
  </complexType>

  <!-- sort -->
  <element name="sort" type="o:Sort"/>
  <complexType name="Sort">
    <complexContent>
      <extension base="o:Container">
	<attribute name="select" type="o:Expression" use="optional"/>
	<attribute name="order" type="o:MixedExpression" use="optional"/>
	<attribute name="data-type " type="o:MixedExpression" use="optional"/>
      </extension>
    </complexContent>
  </complexType>

  <group name="instructions">
    <choice>
      <!-- meta information -->
      <element ref="o:meta"/>

      <!-- conditionals -->
      <element ref="o:choose"/>
      <element ref="o:if"/>
      <element ref="o:while"/>

      <!-- control statements -->
      <element ref="o:for-each"/>
      <element ref="o:return"/>
      
      <!-- simples -->
      <element ref="o:variable"/>
      <element ref="o:set"/>
      <element ref="o:log"/>
      <element ref="o:eval"/>
      <element ref="o:do"/>

      <!-- content generators -->
      <element ref="o:element"/>
      <element ref="o:attribute"/>
      <element ref="o:text"/>
      <element ref="o:comment"/>
      <element ref="o:processing-instruction"/>
      <element ref="o:document"/>

      <!-- definitions -->
      <element ref="o:function"/>
      <element ref="o:procedure"/>
      <element ref="o:type"/>

      <!-- exceptions -->
      <element ref="o:throw"/>
      <element ref="o:catch"/>
      <element ref="o:assert"/>

      <!-- threads -->
      <element ref="o:thread"/>

      <!-- literals -->
      <any namespace="##any" processContents="lax"/>
    </choice>
  </group>

  <!-- general-purpose container type -->
  <complexType name="Container" mixed="true">
    <sequence>
      <group ref="o:instructions" minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
    <!-- <anyAttribute namespace="##other" processContents="skip"/> -->
  </complexType>

  <simpleType name="Expression">
    <restriction base="string">
    <!-- o:Path patterns go here  -->
    </restriction>
  </simpleType>

  <simpleType name="MixedExpression">
    <restriction base="string">
    <!-- curly-braces enclosed o:Path patterns go here  -->
    </restriction>
  </simpleType>

  <simpleType name="QName">
    <!-- QName does not have to be prefix qualified -->
    <union memberTypes="NCName QName"/>
  </simpleType>

</schema>

