<?xml version="1.0" standalone="yes" ?>
<!-- Schematron schema for Constraint on Schemas -->
<!-- This can be placed inside an appinfo element-->
<!-- after the normative declarations for XML    -->
<!-- Schema.                                     -->

<!-- Copyright (C) 1999, Rick Jelliffe           -->
<!-- Use for any purpose except sale or          -->
<!-- inclusion in commercial products is granted -->
<!-- The XML schema draft used is from Dec, 99.  -->
<!-- The draft is incomplete, so this schema may -->
<!-- also be incomplete. Please send comments    -->
<!-- improvements, huge sums of money, to        -->
<!-- ricko@geotempo.com or ricko@allette.com.au  -->
<!-- or ricko@gate.sinica.edu.tw                 -->

<!-- Limitation: QNames and NCNames are not      -->
<!-- treated specially.                          -->

<!-- To Do:  attribute type checking   -->
<!-- first is annotation last is anyAttribute -->
<!-- need to make sure that all checks for attribute
    values check length as well as existence. -->
<!-- check the number of annotations
    and anyAttributes per element is one maximum.
    this is a pattern in its own right, so check
    if it should be part of the annotation element.
    -->

<!DOCTYPE schema
[
    <!ENTITY ordered " minExclusive or maxExclusive or
    minInclusive or maxInclusive or precision or scale ">
    <!ENTITY unordered " pattern or enumeration or
    length or maxLength or minLength  or encoding
    or period or language ">
    <!ENTITY facet " &ordered; or &unordered; ">
    
    
    <!ENTITY ordered-t " minExclusive | maxExclusive | 
    minInclusive | maxInclusive | precision | scale">
    <!ENTITY unordered-t " pattern | enumeration |
    length | maxLength | minLength | encoding
    | period | language ">
    <!ENTITY facet-t " &ordered-t; | &unordered-t; ">
    
    
    <!ENTITY facet-p " parent::minExclusive | parent::maxExclusive | 
    parent::minInclusive | parent::maxInclusive | parent::precision | parent::scale
    | parent::pattern | parent::enumeration |
    parent::length | parent::maxLength | parent::minLength | parent::encoding
    | parent::period | parent::language ">
                    
    <!-- facets than cannot repeat -->
    <!ENTITY facet-c " minExclusive | maxExclusive | 
    minInclusive | maxInclusive | length | maxLength | 
    minLength | encoding | period | length | precision
    | scale | language ">
    
    <!-- common facet constraint -->
    <!ENTITY facet-x " minExclusive | maxExclusive | 
    minInclusive | maxInclusive | length | maxLength | 
    minLength | enumeration | pattern | language ">
    
    <!ENTITY facet-i " minExclusive | maxExclusive | minInclusive | maxInclusive | enumeration   ">
]>

<schema                                                    
    xml:lang="en" >  
    <title>XML Schema Element and Attribute Validator (Dec99 WD)</title>
	<ns prefix='x' uri='http://www.w3.org/XML/1998/namespace'>
<!--
      xmlns="http://www.w3.org/1999/XMLSchema" 
	-->
    <!-- ====================== -->
    <!-- For Structural Schemas -->
    <!-- Elements and Attributes-->
    <!-- ====================== -->  

    <pattern name="Beta Notes">
        <rule context="/*">
            <report test="1=1"
            >This Schematron schema tests most structural constraints
            of the December 1999 Working Draft for XML Schema Structures
            and Datatypes, including the relationships between attribute
            values and allowed content. The deficiencies are: 1) not fully
            tested yet, 2) not namespace-aware (you will have to remove
            xmlns="..." from all schema files, the main and any that are
            included or imported, otherwise it will not work), 3) only
            subtyping the builtin types is checked thoroughly.
            If you use this, please report errors or improvements
            or more helpful asserts to ricko@gate.sinica.edu.tw.
            </report>
            
            <report test="1=1"
            >If you are using this over a slow modem connection and
            the schema user include or import over http, then 
            comment out the reports or asserts which include
            tests of document() in them.
            </report>
        </rule>
   </pattern>

    <pattern name="Top-Level" >
        <rule context="/*">
            <assert test="/schema"
            >This may not be an error, but typically
            the top level element will be 'schema'.
            </assert>
        </rule>
    </pattern>
    
    <pattern name="Elements and Attributes: &lt;schema&gt; "
        href="http://www.w3.org/TR/xmlschema-1" >   

        <rule context="schema">      
            <assert test="count(*) = count(datatype | type | element
            | group | notation | attributeGroup 
            | include | import | annotation
            | unique | key | keyref)"
            >A schema element can contain
            the following elements:
            first any mix and number of
            include, import and annotation; then
            any mix and number of
            datatype, type, element, group,
            notation, attributeGroup,  
            unique, key and keyref.
            </assert>
            <assert test="count(@targetNamespace | @version | @xmlns
            | @extendableDefault | @xml:lang ) 
            = count(attribute::*)"
            >The <name/> element can only have the following attributes:
            targetNamespace, version, xmlns, finalDefault or exactDefault.
            </assert>
            <assert test="not(@extendableDefault) 
            or (@extendableDefault='true') or (@extendableDefault='false')"
            >The extendableDefault attribute on a <name/> element can only be 
            'true' or 'false'.  (Hint: check the spelling and case.) 
            </assert>
        </rule>     
    </pattern>      
    
                                  
    <pattern name="Elements and Attributes: &lt;annotation&gt; "
        href="http://www.w3.org/TR/" >
        <rule context="info | appinfo">
            <assert test="parent::annotation"
            >An <name/> element may only appear in an annotation element.
            </assert>
            <assert test="not(attribute::*) or attribute::source or attribute::xml:lang"
            >An <name/> element may only have a source attribute.
            </assert>
        </rule>      
        <rule context="annotation">
            <assert test="&facet-p; | parent::schema | parent::datatype | parent::restrictions
            | parent::element | parent::group | parent::attribute | parent::attributeGroup | parent::type"
            >An annotation is only expected inside any of the following elements:
            schema, type, restrictions, element, attribute, group, attributeGroup,
            datatype or the facets of datatypes: &facet;
            </assert>
        </rule>                    
    </pattern>            
                      
    <pattern name="Elements and Attributes: &lt;any&gt; "
        href="http://www.w3.org/TR/xmlschema-1" >
        <rule context="any">
            <!-- Parent -->
            <assert test="parent::type | parent::restrictions
            | parent::group "
            >The <name/> element must be a child of type
            or restrictions or group
            </assert>
            
            <!-- Children -->
            <assert test="not(*)"
            >The class element cannot contain subelements.
            </assert>                   
            
            <!-- Attributes -->
            <assert test="count( @minOccurs | @maxOccurs | @namespace |
            @xml:lang ) 
            = count(attribute::*)"
            >The <name/> element can only have the following attributes:
            maxOccurs, minOccurs, namespace.
            </assert>                      
        </rule>
    </pattern>                       
    
    <pattern name="Elements and Attributes: &lt;anyAttribute&gt; "
        href="http://www.w3.org/TR/xmlschema-1" >
        <rule context="anyAttribute">
            <!-- Parent -->
            <assert test="parent::type | parent::restrictions |
            parent::attributeGroup"
            >The <name/> element must be a child of type
            or restrictions or attributeGroup.
            </assert>
            
            <!-- Children -->
            <assert test="not(*)"
            >The <name/> element cannot contain subelements.
            </assert>                   
            
            <!-- Attributes -->
            <assert test="not(attribute::*)  or @namespace "
            >The <name/> element can have a namespace attribute.
            </assert>
        </rule>
    </pattern>                      
                       
  
    
     <pattern name="Elements and Attributes: &lt;attribute&gt; "
        href="http://www.w3.org/TR/xmlschema-1" >
        <rule context="attribute">
            <!-- Parent -->
            <assert test="parent::attributeGroup | parent::type | 
            parent::restrictions"
            >The <name/> element must be a child of asttrGroup
            or type or restrictions.
            </assert>
            
            <!-- Children -->
            <assert test="count(*) = count( annotation | datatype)"
            >The <name/> element can contain 
            and optional annotation element followed by
            an optional datatype element.    
            </assert>                   
            
            <!-- Attributes -->
            <assert test="count(@name  | @type
            | @minOccurs | @maxOccurs | @default | @fixed | @xml:lang ) 
            = count(attribute::*)"
            >The <name/> element can only have the following attributes:
            name,  type minOccurs, maxOccurs,  
            default, fixed.
            </assert>                         
            <report test="@default and @fixed"
            >In the <name/> element,
            the attribute default should not be used
            if the attribute fixed is used.
            </report>     
                                
            <report test="@type='attr' and datatype"
            >In the <name/> element,
            the datatype subelement cannot be specified
            if the value of the attribute type is 'attr'.
            </report>                         
        </rule>
    </pattern> 
    
       <pattern name="Elements and Attributes: &lt;attributeGroup&gt; "
        href="http://www.w3.org/TR/xmlschema-1" >
        <rule context="attributeGroup">
            <!-- Parent -->
            <assert test="parent::schema | parent::type | 
            parent::restrictions | parent::attributeGroup "
            >The <name/> element must be a child of schema
            or type or restrictions or attributeGroup.
            </assert>
            
            <!-- Children -->
            <assert test="count(*) = count( annotation |
            attribute | attributeGroup | anyAttribute)"
            >The <name/> element can contain an optional
            'annotation' elemment; then  'attribute' or 
            'attributeGroup' in any mix and number; 
            and then an optional final
            'anyAttribute' element.
            </assert>                   
            <assert test="count(anyAttribute) &lt; 2"
            >The <name/> element cannot have more than one subelement
            anyAttribute.
            </assert>
                  
            <assert test="count(annotation) &lt; 2"
            >The <name/> element cannot have more than one subelement
            annotation.
            </assert>
            <!-- TODO: positional in content model not done!!! -->
            
            <!-- Attributes -->
            <assert test="count(@name | @ref  | @xml:lang ) 
            = count(attribute::*)"
            >The <name/> element can only have the following attributes:
            name, ref.
            </assert>                         
            <report test="@ref and (* | @name)" > 
            >In the <name/> element, the ref attribute should not be
            used if the name subelement is used or if the <name/> element has
            content.
            </report> 
            <!-- add ref if not top-level -->
                                                                                    
        </rule>
    </pattern> 
 

    <pattern name="Elements and Attributes: &lt;datatype&gt; and facets "
        href="http://www.w3.org/TR/" >
        <rule context="datatype">
            <assert test="count( annotation | &facet-t; ) = count (*)"
            >A datatype element can only have annotation or
            facet children.
            </assert>
            <report test="annotation and not(*[position()=1] =annotation)"
            >In a <name/> element, an annotation element must
            come before any facets.
            </report>
            <assert test="@source and string-length(@source &gt; 0)"
            >The <name/> element must have a source attribute.
            </assert>
        </rule>
        <rule context="&facet-t;">
            <assert test="parent::datatype | parent::restrictions"
            >The <name /> facet element can only appear in a datatype 
            or restrictions element.
            </assert>
            <assert test="count( annotation ) = count (*)"
            >The <name/> element can only contain an annotation element.
            </assert>
            <assert test="@value and string-length(@value &gt; 0)"
            >The <name/> element must have a value attribute.
            </assert>
            <assert test="not(@abstract) or (@abstract='true') or 
            (@abstract='false')"
            >The abstract attribute on a <name/> element can only be 
            'true' or 'false'.  (Hint: check the spelling and case.) 
            </assert>
            <assert test="not(@final) or (@final='restriction') or
            (@final='extension') or (@final='#all') "
            >The final attribute on a <name/> element can only be
            'restriction' or 'extension' or '#all'.  
            (Hint: check the spelling and case.) 
            </assert>
            <assert test="count(@value | @abstract | @final | @source | @name) 
            = count(attribute::*)"
            >The <name/> element can only have the following attributes:
            abstract, final, name, source and value.
            </assert>
     
            <assert test=" self::enumeration or self::pattern or count( parent::*/*[name()= name()]) = 1"
            >The <name/> element cannot be repeated within a single
            datatype.
            </assert>
    
            <assert test="@value"
            >The <name/> element must have a 'value' attribute.
            </assert>
            
            
            <assert test="not(@name) or count( datatype[@name = @name ]) = 1"
            >In the element <name/>, the name of a datatype must be unique 
            among the datatypes defined in the surrounding schema.
            </assert>             
            <!-- shurely shome mishtake: we need to allow name= builtin -->
            <assert test="not(@name) or count( datatype[@name = @source])  = 1 "
            >In the element <name/>, 
            the name specified must be the name of a datatype in the
            schema in which the user-generated datatype is defined.
            </assert>
            
        </rule>
                     
    </pattern>           
    
    
   
    <!-- These only work one layer, on directly derived types -->
    <pattern name="Elements and Attributes: facets allowed by &lt;datatype source='...' &gt; "          
        href="http://www.w3.org/TR/xmlschema-2" >
               
        <rule context="datatype[@source='string']">
            <assert test="count(*)=count(  annotation |  minExclusive 
            | maxExclusive | minInclusive | maxInclusive | pattern )"
            >A datatype element with a source value of string  
            can only have the following contents:
            annotation | minExclusive | maxExclusive | 
            minInclusive | maxInclusive | pattern.
            </assert>
        </rule>                 
        <rule context="datatype[@source='boolean']">
            <assert test="count(*)=count(  annotation  )"
            >A datatype element with a source value of boolean  
            can only have the following contents:
            annotation.
            </assert>
        </rule>     
        <rule context="datatype[@source='float']" >
            <assert test="count(*)=count( annotation |&facet-i; )"
            >A datatype element with a source value of float
            can only have the following contents:
            annotation | &facet-i;.
            </assert>
        </rule>   
        <rule context="datatype[@source='double']" >
            <assert test="count(*)=count( annotation |&facet-i; )"
            >A datatype element with a source value of double
            can only have the following contents:
            annotation | &facet-i;.
            </assert>
        </rule>   
        <rule context="datatype[@source='decimal']" >
            <assert test="count(*)=
            count( annotation | precision | scale |&facet-i; )"
            >A datatype element with a source value of decimal
            can only have the following contents:
            annotation | precision | scale | &facet-i;.
            </assert>
        </rule>   
        <rule context="datatype[@source='timeInstant']" >
            <assert test="count(*)=
            count( annotation | pattern | &facet-i; )"
            >A datatype element with a source value of timeInstant
            can only have the following contents:
            annotation | pattern | &facet-i;.
            </assert>
        </rule>   
        <rule context="datatype[@source='timeDuration']" >
            <assert test="count(*)=count( annotation |&facet-i; )"
            >A datatype element with a source value of timeDuration
            can only have the following contents:
            annotation | &facet-i;.
            </assert>
        </rule>   
        <rule context="datatype[@source='recurringInstant']" >
            <assert test="count(*)=
            count( annotation | period | pattern | &facet-i; )"
            >A datatype element with a source value of recurringInstant 
            can only have the following contents:
            annotation |period | pattern | &facet-i;.
            </assert>
        </rule>   
        <rule context="datatype[@source='binary']" >
            <assert test="count(*)=
            count( annotation | encoding | length | maxLength |minLength )"
            >A datatype element with a source value of 
            can only have the following contents:
            annotation | encoding | length | maxLength |minLength.
            </assert>
        </rule>                                        
        <rule context="datatype[@source='uri']" >
            <assert test="count(*)=count( annotation | enumeration )"
            >A datatype element with a source value of uri
            can only have the following contents:
            annotation | enumeration.
            </assert>
        </rule>               
        <rule context="datatype[@source='language']" >
            <assert test="count(*)=count( annotation |&facet-x; )"
            >A datatype element with a source value of language
            can only have the following contents:
            annotation | &facet-x;.
            </assert>
        </rule>                                 
        
        <!-- XML Types -->
        <rule context="datatype[@source='NMTOKEN']" >
            <assert test="count(*)=count( annotation | &facet-x; )"
            >A datatype element with a source value of NMTOKEN
            can only have the following contents:
            annotation | &facet-x;.
            </assert>
        </rule>
        <rule context="datatype[@source='Name']">
            <assert test="count(*)=count(  annotation | &facet-x; )"
            >A datatype element with a source value of Name
            can only have the following contents:
            annotation | &facet-x;.
            </assert>
        </rule>
        <rule context="datatype[@source='NMTOKENS']">
            <assert test="count(*)=count(  annotation | &facet-x; )"
            >A datatype element with a source value of NMTOKENS 
            can only have the following contents:
            annotation | &facet-x;.
            </assert>
        </rule>
        <rule context="datatype[@source='QName']">
            <assert test="count(*)=count(  annotation | &facet-x; )"
            >A datatype element with a source value of QName
            can only have the following contents:
            annotation | &facet-x;.
            </assert>
        </rule>
        <rule context="datatype[@source='NCName']">
            <assert test="count(*)=count(  annotation | &facet-x; )"
            >A datatype element with a source value of NCName 
            can only have the following contents:
            annotation | &facet-x;.
            </assert>
        </rule>
        <rule context="datatype[@source='ID']">
            <assert test="count(*)=count(  annotation | &facet-x; )"
            >A datatype element with a source value of ID 
            can only have the following contents:
            annotation | &facet-x;.
            </assert>
        </rule>
        <rule context="datatype[@source='ENTITY']">
            <assert test="count(*)=count( annotation |  &facet-x; )"
            >A datatype element with a source value of ENTITY 
            can only have the following contents:
            annotation | &facet-x;.
            </assert>
        </rule>       
        <rule context="datatype[@source='NOTATION']">
            <assert test="count(*)=count(  annotation | &facet-x; )"
            >A datatype element with a source value of NOTATION 
            can only have the following contents:
            annotation | &facet-x;.
            </assert>
        </rule>   
        <rule context="datatype[@source='IDREF']">
            <assert test="count(*)=count(  annotation | &facet-x; )"
            >A datatype element with a source value of IDREF  
            can only have the following contents:
            annotation | &facet-x;.
            </assert>
        </rule>                 
        <rule context="datatype[@source='IDREFS']">
            <assert test="count(*)=count(  annotation | &facet-x; )"
            >A datatype element with a source value of IDREFS  
            can only have the following contents:
            annotation | &facet-x;.
            </assert>
        </rule>                 
        <rule context="datatype[@source='ENTITIES']">
            <assert test="count(*)=count(  annotation | &facet-x; )"
            >A datatype element with a source value of ENTITIES   
            can only have the following contents:
            annotation | &facet-x;.
            </assert>
        </rule>       
        
        <!-- Numeric types -->          
        <rule context="datatype[@source='integer']">
            <assert test="count(*)=count(  annotation | &facet-i; )"
            >A datatype element with a source value of integer  
            can only have the following contents:
            annotation | &facet-i;.
            </assert>
        </rule>                 
        <rule context="datatype[@source='non-negative-integer']">
            <assert test="count(*)=count(  annotation | &facet-i; )"
            >A datatype element with a source value of non-negative-integer  
            can only have the following contents:
            annotation | &facet-i;.
            </assert>
        </rule>                 
        <rule context="datatype[@source='non-positive-integer']">
            <assert test="count(*)=count(  annotation | &facet-i; )"
            >A datatype element with a source value of non-positive-integer  
            can only have the following contents:
            annotation | &facet-i;.
            </assert>
        </rule>                 
        <rule context="datatype[@source='positive-integer']">
            <assert test="count(*)=count(  annotation | &facet-i; )"
            >A datatype element with a source value of positive-integer  
            can only have the following contents:
            annotation | &facet-i;.
            </assert>
        </rule>                 
        <rule context="datatype[@source='negative-integer']">
            <assert test="count(*)=count(  annotation | &facet-i; )"
            >A datatype element with a source value of  negative-integer 
            can only have the following contents:
            annotation | &facet-i;.
            </assert>
        </rule>                 
        <rule context="datatype[@source='date']">
            <assert test="count(*)=count(  annotation | &facet-i; )"
            >A datatype element with a source value of date  
            can only have the following contents:
            annotation | &facet-i;.
            </assert>
        </rule>                 
        <rule context="datatype[@source='time']">
            <assert test="count(*)=count(  annotation | &facet-i; )"
            >A datatype element with a source value of time  
            can only have the following contents:
            annotation | &facet-i;.
            </assert>
        </rule> 
        <!-- An iteration down a second layer to grandchild derived types
            could be added here. -->                     
    </pattern>          
                                                             
                        



    <pattern name="Elements and Attributes: &lt;element&gt; "
        href="http://www.w3.org/TR/xmlschema-1" >
        <rule context="element">
            <!-- Parent -->
            <assert test="parent::schema | parent::type | 
            parent::restrictions | parent::group "
            >The <name/> element can only be a child of schema
            or type or restrictions or group.
            </assert>
            
            <!-- Children -->
            <assert test="count(*) = count( type | datatype |
            annotation | unique | key | keyref)"
            >The <name/> element can contain an optional
            annotation element; then the type and
            datatype elements, in any mix and number;
            then the key, unique and keyref elements,
            in any mix and number.
            </assert>                   
            
            <!-- Attributes -->
            <assert test="count(@name | @ref | @type
            | @nullable | @equivClass | @abstract | @final 
            | @exact 
            | @minOccurs | @maxOccurs | @default | @fixed | @xml:lang ) 
            = count(attribute::*)"
            >The <name/> element can only have the following attributes:
            name, ref, type, minOccurs, maxOccurs, equivClass,   
            default, fixed, abstract, final, nullable, exact.
            </assert>
            <report test="@type and @ref" 
            >The <name/> element cannot have both the ref attribute
            and the type attribute specified at the same time.
            </report>   
            <report test="@default and @fixed" 
            >The <name/> element cannot have both the default attribute
            and the fixed attribute specified at the same time.
            </report>     
            
            <report test="@name and @ref"  
            >The <name/> element cannot have both the ref attribute
            and the name attribute specified at the same time.
            </report>                                                   
        </rule>
    </pattern> 
        

  
    
    <pattern name="Elements and Attributes: &lt;field&gt; "
        href="http://www.w3.org/TR/xmlschema-1" >
        <rule context="field">
            <!-- Parent -->
            <assert test="parent::unique | parent::key |
            parent::keyref"
            >The <name/> element must be a child of unique
            or key or keyref.
            </assert>
            
            <!-- Children -->
            <assert test="not(*)"
            >The <name/> element cannot contain subelements.
            </assert>
            <assert test="string-length(text()) &gt; 0"
            >The <name/> element must contain a value.
            </assert>
            
            <!-- Attributes -->
            <report test="attribute::*"
            >The <name/> element cannot have an attribute.
            </report>
        </rule>
    </pattern>
                    
      <pattern name="Elements and Attributes: &lt;group&gt; "
        href="http://www.w3.org/TR/xmlschema-1" >
        <rule context="group">
            <!-- Parent -->
            <assert test="parent::schema | parent::type | 
            parent::restrictions | parent::group"
            >The <name/> element can only be a child of schema
            or type or restrictions or group.
            </assert>
            
            <!-- Children -->
            <assert test="count(*) = count( annotation | element | group | any)"
            >The <name/> element can contain an
            optional 'annotation' element, followed by
            the 'element', 'group' and
            'any' elements, in any mix and number.
            </assert>                   
            
            <!-- Attributes -->
            <assert test="count(@name | @ref | @minOccurs | @maxOccurs 
            | @order | @xml:lang ) 
            = count(attribute::*)"
            >The <name/> element can only have the following attributes:
            name, ref, minOccurs, maxOccurs,  
            order.
            </assert>  
             <assert test="not(@order) or (@order='choice') or 
            (@order='seq') or (@order='all') "
            >The order attribute on a <name/> element can only be 
            'choice', 'seq', or 'all'.  
            (Hint: check the spelling and case.) 
            </assert>     
            <report test="group and @order='all'"
            >In the <name/> element,
            if the attribute order has the value all,
            the group sub-element is not allowed.
            </report>
            <report test="@order='all' and not(parent::type)"
            >In the <name/> element,
            if the attribute order has the value 'all',
            then the <name/> element must be at
            the top level of the content model.
            </report><!-- ??? -->
                                                                                    
        </rule>
    </pattern> 
    
                                    
    
    <pattern name="Elements and Attributes: &lt;import&gt; "
        href="http://www.w3.org/TR/xmlschema-1" >
        <rule context="import">
            <!-- Parent -->
            <assert test="parent::schema"
            >The <name/> element must be a child of schema.
            </assert>
            
            <!-- Children -->
            <assert test="(normalize-space(.)='') and (count(*) = 0)"
            >The <name/> element cannot contain subelements.
            </assert>                   
            
            <!-- Attributes -->
            <assert test="count(attribute::*) = 
            count(@schemaLocation | @namespace ) "
            >The <name/> element can only have schemaLocation and
            namespace attributes.
            </assert>
            <assert test="@namespace"
            >The <name/> element must have a namespace attribute.
            </assert>      
             
            <assert test="(string-length(@schemaLocation) &gt; 0) and
            document(@schemaLocation)/schema"
            >On the element <name/> the schemaLocation
            attribute should give the URI of an XML
            schema.
            </assert>
        
        </rule>
    </pattern>               
   
    <pattern name="Elements and Attributes: &lt;include&gt; "
        href="http://www.w3.org/TR/xmlschema-1" >
        <rule context="include">
            <!-- Parent -->
            <assert test="parent::schema"
            >The <name/> element must be a child of schema.
            </assert>
            
            <!-- Children -->
            <assert test="(normalize-space(.)='') and (count(*) = 0)"
            >The <name/> element cannot contain subelements.
            </assert>                   
            
            <!-- Attributes -->
            <assert test="count(attribute::*) = count(@schemaLocation) "
            >The <name/> element can only have a schemaLocation attribute.
            </assert>
            <assert test="@schemaLocation"
            >The <name/> element must have a schemaLocation attribute.
            </assert>
        
            <assert test="(string-length(@schemaLocation) &gt; 0) and 
            document(@schemaLocation)/schema"
            >On the element <name/> the schemaLocation
            attribute should give the URI of an XML
            schema.
            </assert>
       
        </rule>
    </pattern>  
    
    
    
    <pattern name="Elements and Attributes: &lt;key&gt; and  &lt;unique&gt; "
        href="http://www.w3.org/TR/xmlschema-1" >
        <rule context="unique | key">
            <!-- Parent -->
            <assert test="parent::schema | parent::element"
            >The <name/> element must be a child of schema
            or element.
            </assert>
            
            <!-- Children -->
            <assert test="count(*) = count (selector | field) "
            >The <name/> element cannot contain 
            a selector element followed by one or
            more field elements.
            </assert>                   
            <assert test="count(selector) = 1"
            >The <name/> element must contain one 'selector'
            element.
            </assert>                   
            <assert test="field "
            >The <name/> element must contain at least one 'field'
            element.
            </assert>
            
            <!-- Attributes -->
           <assert test="count(@name | @xml:lang ) 
            = count(attribute::*)"
            >The <name/> element can only have the following attribute:
            name.
            </assert>
            <assert test="not(@name) or ( string-length(@name) &gt; 0)"
            >The <name/> element should have a name attribute.
            </assert>                                                 
        </rule>
    </pattern>          

    <pattern name="Elements and Attributes: &lt;keyref&gt; "
        href="http://www.w3.org/TR/xmlschema-1" >
        <rule context="keyref">
            <!-- Parent -->
            <assert test="parent::schema | parent::element"
            >The <name/> element must be a child of schema
            or element.
            </assert>
            
            <!-- Children -->
            <assert test="count(*) = count (selector | field) "
            >The <name/> element cannot contain 
            a selector element followed by one or
            more field elements.
            </assert>                   
            <assert test="count(selector) = 1"
            >The <name/> element must contain one 'selector'
            element.
            </assert>                   
            <assert test="field "
            >The <name/> element must contain at least one 'field'
            element.
            </assert>
            
            <!-- Attributes -->
           <assert test="count(@name | @refer |@xml:lang ) 
            = count(attribute::*)"
            >The <name/> element can only have the following attribute:
            name, refer.
            </assert>
            <assert test="not(@name) or ( string-length(@name) &gt; 0)"
            >The <name/> element should have a name attribute.
            </assert>                     
            <assert test="not(@refer) or ( string-length(@refer) &gt; 0)"
            >The <name/> element should have a refer attribute.
            </assert>                                                 
        </rule>
    </pattern>          

                     
    
    <pattern name="Elements and Attributes: &lt;notation&gt; "
        href="http://www.w3.org/TR/xmlschema-1" >
        <rule context="notation">
            <!-- Parent -->
            <assert test="parent::schema"
            >The <name/> element must be a child of schema
            </assert>
            
            <!-- Children -->
            <assert test="not(*)"
            >The <name/> element cannot contain subelements.
            </assert>                   
            
            <!-- Attributes -->
           <assert test="count(@name  | @public |
           @system | @xml:lang ) 
            = count(attribute::*)"
            >The <name/> element can only have the following attributes:
            name,  public, system.
            </assert>
            <assert test="@name and ( string-length(@name) &gt; 0)"
            >The <name/> element should have a name attribute.
            </assert>
            <assert test="@public and ( string-length(@public) &gt; 0)"
            >The <name/> element should have a public attribute.
            </assert>
        </rule>
    </pattern>   
     <pattern name="Elements and Attributes: &lt;restrictions&gt; "
        href="http://www.w3.org/TR/xmlschema-1" >
        <rule context="restrictions" >
            <!-- Parent -->
            <assert test="parent::type"
            >The <name/> element must be a child of type.
            </assert>
            
            <!-- Children -->       
            <assert test="count(*) = count(annotation | &facet-t; | restrictions |
            element | group | any | sic | attribute | attributeGroup |
            anyAttribute)"
            >The restrictions element can contain the following
            elements:
            ; then any
            mix of element, group and any (if the content
            attribute has the value 'mixed' or 'elemOnly');
            then any mix of attribute and 
            attributeGroup; and lastly an optional anyAttribute. 
            </assert>  
        </rule>                                        
    </pattern>                       
                          

                                             
    <pattern name="Elements and Attributes: &lt;selector&gt; "
        href="http://www.w3.org/TR/xmlschema-1" >
        <rule context="selector">
            <!-- Parent -->
            <assert test="parent::unique | parent::key |
            parent::keyref"
            >The <name/> element must be a child of unique
            or key or keyref.
            </assert>
            
            <!-- Children -->
            <assert test="not(*) "
            >The <name/> element cannot contain subelements.
            </assert>
            <assert test="string-length(text()) &gt; 0"
            >The <name/> element must contain a value.
            </assert>
            
            <!-- Attributes -->
            <report test="attribute::*"
            >The <name/> element cannot have an attribute.
            </report>
        </rule>
    </pattern>
    
    <pattern name="Elements and Attributes: &lt;sic&gt; "
        href="http://www.w3.org/TR/xmlschema-1" >
        <rule context="sic">
            <!-- Parent -->
            <assert test="parent::restrictions"
            >The <name/> element must be a child of restrictions.
            </assert>
            
            <!-- Children -->
            <assert test="count(*) = 0"
            >The <name/> element cannot contain subelements.
            </assert>                   
            
            <!-- Attributes -->
            <report test="attribute::*"
            >The <name/> element should have no attributes.
            </report>
        </rule>
    </pattern>                 
  <pattern name="Elements and Attributes: &lt;type&gt; "
        href="http://www.w3.org/TR/xmlschema-1" >
        <rule context="type">
            <!-- Parent -->
            <assert test="parent::schema | parent::element "
            >The <name/> element must be a child of schema
            or element.
            </assert>
            
            <!-- Children -->
            <assert test="count(*) = count(annotation | restrictions |
            element | group | any |attribute | attributeGroup |
            anyAttribute)"
            >The type element can contain the following
            elements:
            an optional annotation element; 
            then either restriction or any
            mix of element, group and any (if the content
            attribute has the value 'mixed' or 'elemOnly');
            then any mix of attribute and 
            attributeGroup; and lastly an optional anyAttribute. 
            </assert>                   
            
            <!-- Attributes -->
            <assert test="count(@name | @content | @abstract
            | @final | @exact | @source | @derivedBy | @xml:lang ) 
            = count(attribute::*)"
            >The <name/> element can only have the following attributes:
            name, content, abstract, final, exact, 
            source, derivedBy.
            </assert>
            <assert test="not(@content) or (@content='textOnly') or 
            (@content='mixed') or (@content='elemOnly') or 
            (@content='empty')" > 
            >The content attribute on a <name/> element can only be 
            'textOnly', 'mixed', 'elemOnly' or 'empty'.  
            (Hint: check the spelling and case.) 
            </assert>
    
            <assert test="not(@abstract) or (@abstract='true') or 
            (@abstract='false')"
            >The abstract attribute on a <name/> element can only be 
            'true' or 'false'.  (Hint: check the spelling and case.) 
            </assert>                                                      
            <assert test="not(restrictions) or (restrictions and @derivedBy='restriction')"
            >The <name/> element can only have a restrictions subelement
            if the attribute derivedBy has the value 'restriction'.
            </assert>
            
            
            <assert test="not(@name) or (count(//type[@name= current()/@name]) = 1)"
            >The same NCName must not appear in two definitions
            or declarations of the same type.
            </assert>
        </rule>
    </pattern>                       
                  
    <pattern name="Elements and Attributes: contents allowed by &lt;type content='...'&gt; "
        href="http://www.w3.org/TR/xmlschema-1" >
        <rule context="type[@content='textOnly']">
            <report test="element | group | any"
            >If the attribute content on the <name/> 
            element has the value 'textOnly', 
            the following elements cannot be used:
            element, group, any.
            </report>
        </rule>
        <rule context="type[@content='empty']">
            <report test="element | group | any"
            >If the attribute content on the <name/> 
            element has the value 'empty', 
            the following elements cannot be used:
            element, group, any.
            </report>
        </rule>
    </pattern>                         
       
    <!-- ====================== -->
    <!-- "Constraints on        -->
    <!-- Schemas (SC)           -->
    <!-- ====================== -->
    <!-- for effiency, these can be merged later with their natural pattern -->
    <pattern name="Constraints on Schema: duplications "
        href="http://www.w3.org/TR/xmlschema-1#6.2" >
                     
        <rule context="attributeGroup/@ref">
            <assert test="count(parent::*/attributeGroup[@ref= @ref])=1"
            >An attribute group should not be referenced by
            name more than once per element.
            </assert>
            <assert test="//attributeGroup[@name= @ref]"
            >An attribute group reference should refer
            to an attribute group that has been defined
            elsewhere in the in schema.
            </assert>
            <assert test="@name=@ref"
            >An attribute group should not refer to itself.
            </assert>
        </rule>                                                   
        <rule context="attribute/@name">    <!-- ?? -->
            <assert test="count(parent::*/attribute[@name= current()]/@name) = 1"
            >An attribute should not be defined twice.
            </assert>
        </rule>                                              
        <rule context="element/@name">
            <assert test="count(//element[@name= @name]) = 1"
            >An element cannot be declared more than once.
            </assert>
        </rule>                                                 
        <rule context="group[@order='alt']/element/@name">
            <assert test="count(parent::*/element[@ref= @name]) = 1"
            >A choice group should not have choices between
            the same element.
            </assert>
        </rule>
        <rule context="group[@order='alt']/element/@ref">
            <assert test="count(parent::*/element[@ref= @ref]) = 1"
            >A choice group should not have choices between
            the same element. (If this seems strange in
            context, please ignore this message: ambiguity
            is ambiguous in the XML Schema draft.>
            </assert><!-- Is this correct? -->
        </rule>   
         <rule context="length"> 
            <report test="../maxLength"
            >It is an error for both length and maxLength
            to be specified for the same datatype. 
            </report>
            <report test="../minLength"
            >It is an error for both length and minLength
            to be specified for the same datatype. 
            </report>                       
        </rule>                                        
        <rule context="minExclusive">
            <report test="../minInclusive"
            >It is an error for both minExclusive and minInclusive
            to the specified for the same datatype. 
            </report>
        </rule>                                      
        <rule context="maxExclusive">
            <report test="../maxInclusive"
            >It is an error for both minExclusive and maxInclusive
            to the specified for the same datatype. 
            </report>
        </rule>                                           
    </pattern>  
                       
    <pattern name="Constraints on Schema: value constraints"
        href="http://www.w3.org/TR/xmlschema-1#6.2.3.6" >
        <!-- mooted -->
        <rule context="*/@maxOccurs/@minOccurs">
            <assert test="@minOccurs &lt;= @maxOccurs"
            >In the <name/> element, the value of
            maxOccurs must be greater or equal to 
            the value of minOccurs.
            </assert>
        </rule>        
        <rule context="*/@maxOccurs">
            <assert test="@maxOccurs &gt; 0"
            >In the <name/> element, the value of
            maxOccurs must be greater or equal to 1
            (which is the default value of maxOccurs.)
            </assert>
        </rule>
        <rule context="*/@minOccurs">
            <assert test="@minOccurs &lt; 1"
            >In the <name/> element, the value of
            minOccurs must be greater or equal to 1
            (which is the default value of maxOccurs.
            </assert>
        </rule>              
        <rule context="scale">
            <report test="(../precision) and (text() &gt; ../precision/text())"
            >It is an error for scale to be greater-than precision.
            </report>
        </rule>               
    </pattern>                           

 
 
    <!-- ====================== -->
    <!-- For Data Types:        -->
    <!-- Elements Types         -->
    <!-- ====================== -->
                                                                           
               
</schema>
