<?xml version="1.0" ?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
  <start>
    <element name="wdkModel">
      <attribute name="name" />
      <attribute name="displayName" />
      <optional>
          <element name="introduction">
              <text />
          </element>
      </optional>
      <oneOrMore>
        <choice>
          <ref name="questionSet" />
          <ref name="querySet" />
          <ref name="queryNameList" />
          <ref name="recordClassSet" />
          <ref name="paramSet" />
          <ref name="xmlQuestionSet" />
          <ref name="xmlRecordClassSet" />
        </choice>
      </oneOrMore>
    </element>
  </start>


  <!-- Schema grouping elements  -->
  <define name="queries">
    <choice>
      <ref name="sqlQuery" />
    </choice>
  </define>  
  
  <define name="params">
    <choice>
      <ref name="stringParam" />
      <ref name="flatVocabParam" />
    </choice>
  </define>
  
  <define name="columns">
    <choice>
      <ref name="column" />
      <ref name="textColumn" />
      <ref name="linkColumn" />
    </choice>
  </define>
    
  <define name="attributes">
    <choice>
      <ref name="textAttribute" />
      <ref name="linkAttribute" />
    </choice>
  </define>
    

  <!-- Schema subtype shared elements -->
  <define name="ColumnBaseContents">
    <attribute name="name" />
    <optional>
      <attribute name="inSummary" />
    </optional>
    <optional>
      <attribute name="truncateToRef" />
    </optional>
    <optional>
      <attribute name="displayName" />
    </optional>
    <optional>
      <attribute name="help" />
    </optional>
    <optional>
      <attribute name="specialType" />
    </optional>
    <optional>
      <attribute name="isInternal" />
    </optional>
  </define>

  <define name="ParamBaseContents">
    <attribute name="name" />
    <optional>
      <attribute name="prompt" />
    </optional>
    <optional>
      <attribute name="help" />
    </optional>
  </define>

  <define name="QueryBaseContents">
    <optional>
      <attribute name="name" />
    </optional>
    <optional>
      <attribute name="displayName" />
    </optional>
    <optional>
      <attribute name="isCacheable" />
    </optional>
    <optional>
        <element name="description">
            <text />
        </element>        
    </optional>
    <zeroOrMore>
      <element name="paramRef">
        <attribute name="ref" />
      </element>
    </zeroOrMore>
    <oneOrMore>
      <ref name="columns" />
    </oneOrMore>
  </define>
  
  <!-- Instance grouping elements -->
  <define name="querySet">
    <element name="querySet">
      <attribute name="name" />
      <oneOrMore>
        <ref name="queries" />
      </oneOrMore>
    </element>
  </define>

  <define name="recordClassSet">
    <element name="recordClassSet">
      <attribute name="name" />
      <oneOrMore>
        <ref name="recordClass" />
      </oneOrMore>
    </element>
  </define>

  <define name="questionSet">
    <element name="questionSet">
      <attribute name="name" />
      <attribute name="displayName" />
      <optional>
          <element name="description">
              <text />
          </element>        
      </optional>
      <optional>
          <attribute name="isInternal" />
      </optional>
      <oneOrMore>
        <ref name="question" />
      </oneOrMore>
    </element>
  </define>

  <define name="paramSet">
    <element name="paramSet">
      <attribute name="name" />
      <oneOrMore>
        <ref name="params" />
      </oneOrMore>
    </element>
  </define>


  <define name="queryNameList">
    <element name="queryNameList">
      <attribute name="name" />
      <oneOrMore>
        <element name="fullQueryName">
          <attribute name="fullQueryName" />
        </element>
      </oneOrMore>
    </element>
  </define>
   
   
  <!-- Queries -->
  <define name="sqlQuery">
    <element name="sqlQuery">
      <ref name="QueryBaseContents" />
      <element name="sql">
        <text />
      </element>
    </element>
  </define>

  
  <!-- Params -->
  <define name="stringParam">
    <element name="stringParam">
      <ref name="ParamBaseContents" />
      <optional>
        <attribute name="default" />
      </optional>
      <optional>
        <attribute name="regex" />
      </optional>
      <optional>
        <attribute name="sample" />
      </optional>
            <optional>
        <attribute name="substitute" />
      </optional> 
    </element>
  </define>
    
  <define name="flatVocabParam">
    <element name="flatVocabParam">
      <ref name="ParamBaseContents" />
      <optional>
        <attribute name="multiPick" />
      </optional>
      <attribute name="queryRef" />
    </element>
  </define>
   
  <!-- Columns -->
  <define name="column">
    <element name="column">
      <ref name="ColumnBaseContents" />
    </element>
  </define>
    
  <define name="textColumn">
    <element name="textColumn">
      <ref name="ColumnBaseContents" />
      <attribute name="text" />
    </element>
  </define>
  
  
  <define name="linkColumn">
    <element name="linkColumn">
      <ref name="ColumnBaseContents" />
      <attribute name="visible" />
      <element name="url">
        <text />
      </element>
    </element>
  </define>
  
  
  <!-- RecordClass -->
  <define name="recordClass">
    <element name="recordClass">
      <attribute name="name" />
      <attribute name="type" />
      <attribute name="idPrefix" />
      <optional>
         <attribute name="attributeOrdering" />
      </optional>

      <!-- the following attribute & element is used by two-part primary key -->
      <optional>
         <attribute name="delimiter" />
      </optional>
      <optional>
         <element name="projectParamRef">
             <attribute name="ref" />
         </element>
      </optional>

      <zeroOrMore>  
        <element name="attributeQueryRef">
          <attribute name="ref" />
        </element>
      </zeroOrMore>
   
      <zeroOrMore>
        <element name="tableQueryRef">
          <attribute name="ref" />
        </element>
      </zeroOrMore>
      <zeroOrMore>
        <ref name="attributes" />
      </zeroOrMore>
      <zeroOrMore>
        <element name="nestedRecord">
            <attribute name="questionRef" />
        </element>
      </zeroOrMore>
      <zeroOrMore>
        <element name="nestedRecordList">
            <attribute name="questionRef" />
        </element>
      </zeroOrMore>
    </element>
  </define>
    


  <!-- Question -->
  <define name="question">
    <element name="question">
      <attribute name="name" />
      <attribute name="displayName" />
      <attribute name="recordClassRef" />
      <attribute name="queryRef" />
      <optional>
           <attribute name="summaryAttributesRef" />
      </optional>
      <element name="description">
          <text />
      </element>        
      <optional>          
       
         <element name="help">
             <text />
         </element>        
      </optional>
    </element>
  </define>
    
  <!-- Attributes -->
  <define name ="textAttribute">
    <element name="textAttribute">
      <attribute name="name" />
      <optional> 
        <attribute name="displayName" />
      </optional>
      <optional> 
        <attribute name="truncateToRef" />
      </optional>
      <element name="text">
        <text />
      </element>
    </element>
  </define>

  <define name ="linkAttribute">
    <element name="linkAttribute">
      <attribute name="name" />
      <optional> 
        <attribute name="displayName" />
      </optional>
      <attribute name="visible" />
      <element name="url">
        <text />
      </element>
    </element>
  </define>

  <!-- Set for xmlAnswers -->

  <define name="xmlRecordClassSet">
    <element name="xmlRecordClassSet">
      <attribute name="name" />
      <oneOrMore>
        <ref name="xmlRecordClass" />
      </oneOrMore>
    </element>
  </define>

  <define name="xmlQuestionSet">
    <element name="xmlQuestionSet">
      <attribute name="name" />
      <attribute name="displayName" />
      <optional>
          <element name="description">
              <text />
          </element>        
      </optional>
      <optional>
          <attribute name="isInternal" />
      </optional>
      <oneOrMore>
        <ref name="xmlQuestion" />
      </oneOrMore>
    </element>
  </define>

  <define name="xmlQuestion">
     <element name="xmlQuestion">
        <attribute name="name" />
        <attribute name="displayName" />
        <attribute name="recordClassRef" />
        <attribute name="xmlDataURL" />
        <optional>
           <attribute name="xslURL" />
        </optional>
        <optional>
           <attribute name="summaryAttributesRef" />
        </optional>
        <element name="description">
           <text />
        </element>        
        <optional>          
           <element name="help">
              <text />
           </element>        
        </optional>
     </element>
  </define>

  <define name="xmlRecordClass">
     <element name="xmlRecordClass">
        <attribute name="name" />
        <attribute name="type" />
        <attribute name="idPrefix" />
        <optional>
           <attribute name="delimiter" />
        </optional>
        <optional>
           <attribute name="attributeOrdering" />
        </optional>
        <zeroOrMore>  
           <ref name="attributeField" />
        </zeroOrMore>
        <zeroOrMore>
           <ref name="tableField" />
        </zeroOrMore>
        <zeroOrMore>
           <ref name="xmlRecordClass" />
        </zeroOrMore>
     </element>
  </define>

  <define name ="tableField">
     <element name="tableField">
        <attribute name="name" />
        <optional>
           <attribute name="displayName" />
        </optional>
        <optional> 
           <attribute name="help" />
        </optional>
        <optional> 
           <attribute name="isInternal" />
        </optional>
        <optional> 
           <attribute name="type" />
        </optional>
        <oneOrMore>
           <ref name="attributeField" />
        </oneOrMore>
     </element>
  </define>

  <define name ="attributeField">
     <element name="attributeField">
        <attribute name="name" />
        <optional> 
           <attribute name="displayName" />
        </optional>
        <optional> 
           <attribute name="help" />
        </optional>
        <optional> 
           <attribute name="isInternal" />
        </optional>
        <optional> 
           <attribute name="type" />
        </optional>
     </element>
  </define>
 
</grammar>
