You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@forrest.apache.org by je...@apache.org on 2002/11/04 10:13:05 UTC

cvs commit: xml-forrest/src/resources/schema/relax xslt.rng

jefft       2002/11/04 01:13:05

  Modified:    .        status.xml
               src/resources/forrest-shbat forrest.build.xml
               src/resources/fresh-site forrest.properties
  Added:       src/resources/schema/relax xslt.rng
  Log:
  - Validate user skin and resource XSLTs
  - Provide a hierarchical inheritable system for overriding validation settings
    in any part of a Forrest project.
  
  Revision  Changes    Path
  1.29      +9 -0      xml-forrest/status.xml
  
  Index: status.xml
  ===================================================================
  RCS file: /home/cvs/xml-forrest/status.xml,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- status.xml	4 Nov 2002 04:31:38 -0000	1.28
  +++ status.xml	4 Nov 2002 09:13:05 -0000	1.29
  @@ -103,6 +103,15 @@
   
     <changes>
      <release version="0.1" date="2002">
  +    <action dev="JT" type="add" context="validation">
  +     XML validation is now fully configurable through a hierarchical set of
  +     <code>forrest.validation.*{includes,excludes,failonerror}</code>
  +     properties.
  +    </action>
  +    <action dev="JT" type="add" context="validation">
  +     Validate XSLTs in user skins and <code>resources/stylesheets</code>
  +     directories.
  +    </action>
       <action dev="DC" type="add" context="docs">
        Added new document <link href="compliance.html">Standards Compliance</link>
        Thanks to Robert Koberg.
  
  
  
  1.9       +140 -43   xml-forrest/src/resources/forrest-shbat/forrest.build.xml
  
  Index: forrest.build.xml
  ===================================================================
  RCS file: /home/cvs/xml-forrest/src/resources/forrest-shbat/forrest.build.xml,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- forrest.build.xml	3 Nov 2002 10:57:46 -0000	1.8
  +++ forrest.build.xml	4 Nov 2002 09:13:05 -0000	1.9
  @@ -22,7 +22,12 @@
                Call this through the 'forrest' command
     </description>
     
  -  
  +  <taskdef name="jing" classname="com.thaiopensource.relaxng.util.JingTask">
  +    <classpath>
  +      <fileset dir="${forrest.home}/WEB-INF/lib" includes="*.jar" />
  +    </classpath>
  +  </taskdef>
  +
   
   <!-- ***************************************************************** -->
   <!-- ***************************************************************** -->
  @@ -76,15 +81,10 @@
       <property name="project.schema-dir" value="${project.content-dir}/resources/schema" />
       <property name="project.skins-dir"   value="${project.content-dir}/skins" />
       <property name="project.skinconf"    value="${project.content-dir}/skinconf.xml" />
  -    <available property="project.skinconf.present" file="${project.skinconf}" type="file"/>
       <property name="project.conf-dir"     value="${project.content-dir}/conf" />
       <property name="project.lib-dir"     value="${project.content-dir}/lib" />
       <property name="project.classes-dir" value="${project.content-dir}/classes" />
   
  -    <property name="forrest.validate.failonerror" value="true" />
  -    <property name="forrest.validate.includes" value="*.x*"/>
  -    <property name="forrest.validate.excludes" value=""/>
  -
       <!-- checks for presence of required classes and/or resources -->
       <property name="tools.jar"           location="${java.home}/../lib/tools.jar"/>
       <available file="${tools.jar}"       property="tools.jar.present"/>
  @@ -93,16 +93,104 @@
       <antcall target="echo-settings" />
     </target>
   
  +  <target name="examine-proj" depends="init-props">
  +    <available property="conf.present" file="${project.conf-dir}" type="dir"/>
  +    <available property="sitemap.present" file="${project.sitemap}"/>
  +    <available property="xdocs.present" file="${project.xdocs-dir}" type="dir"/>
  +    <available property="images.present" file="${project.images-dir}" type="dir"/>
  +    <available property="schema.present" file="${project.schema-dir}" type="dir"/>
  +    <available property="stylesheets.present" file="${project.stylesheets-dir}" type="dir"/>
  +    <available property="lib.present" file="${project.lib-dir}" type="dir"/>
  +    <available property="classes.present" file="${project.classes-dir}" type="dir"/>
  +    <available property="skins.present" file="${project.skins-dir}" type="dir"/>
  +    <available property="skinconf.present" file="${project.skinconf}"/>
  +    <available property="status.present" file="${project.status}"/>
  +  </target>
  +
  +  <target name="validation-props" depends="examine-proj">
  +    <!-- Validation flags -->
  +
  +    <property name="forrest.validate" value="true" />
  +    <condition property="validate">
  +      <istrue value="${forrest.validate}"/>
  +    </condition>
  +    <property name="forrest.validate.failonerror" value="true" />
  +    <property name="forrest.validate.includes" value="**/*"/>
  +    <property name="forrest.validate.excludes" value=""/>
  +
  +    <property name="forrest.validate.xdocs" value="${forrest.validate}"/>
  +    <condition property="validate.xdocs">
  +      <and>
  +        <istrue value="${forrest.validate.xdocs}"/>
  +        <isset property="xdocs.present"/>
  +      </and>
  +    </condition>
  +    <property name="forrest.validate.xdocs.includes" value="*.x*"/>
  +    <property name="forrest.validate.xdocs.excludes" value=""/>
  +    <property name="forrest.validate.xdocs.failonerror"
  +      value="${forrest.validate.failonerror}" />
  +
  +    <property name="forrest.validate.skinconf" value="${forrest.validate}"/>
  +    <condition property="validate.skinconf">
  +      <and>
  +        <istrue value="${forrest.validate.skinconf}"/>
  +        <isset property="skinconf.present"/>
  +      </and>
  +    </condition>
  +    <basename file="${project.skinconf}" property="skinconf-file}"/>
  +    <property name="forrest.validate.skinconf.includes" value="${skinconf-file}"/>
  +    <property name="forrest.validate.skinconf.excludes" value=""/>
  +    <property name="forrest.validate.skinconf.failonerror"
  +      value="${forrest.validate.failonerror}" />
  +
  +    <property name="forrest.validate.stylesheets" value="${forrest.validate}"/>
  +    <condition property="validate.stylesheets">
  +      <and>
  +        <istrue value="${forrest.validate.stylesheets}"/>
  +        <isset property="stylesheets.present"/>
  +      </and>
  +    </condition>
  +    <property name="forrest.validate.stylesheets.includes" value="**/*.xsl"/>
  +    <property name="forrest.validate.stylesheets.excludes" value=""/>
  +    <property name="forrest.validate.stylesheets.failonerror"
  +      value="${forrest.validate.failonerror}" />
  +
  +    <property name="forrest.validate.skins" value="${forrest.validate}"/>
  +    <condition property="validate.skins">
  +      <and>
  +        <istrue value="${forrest.validate.skins}"/>
  +        <isset property="skins.present"/>
  +      </and>
  +    </condition>
  +    <property name="forrest.validate.skins.includes" value="**/*"/>
  +    <property name="forrest.validate.skins.excludes" value="**/*.xsl"/>
  +    <property name="forrest.validate.skins.failonerror"
  +      value="${forrest.validate.failonerror}" />
  +
  +    <property name="forrest.validate.skins.stylesheets" value="${forrest.validate.skins}"/>
  +    <condition property="validate.skins.stylesheets">
  +      <and>
  +        <istrue value="${forrest.validate.skins.stylesheets}"/>
  +        <isset property="skins.present"/>
  +      </and>
  +    </condition>
  +    <property name="forrest.validate.skins.stylesheets.includes" value="**/*.xsl"/>
  +    <property name="forrest.validate.skins.stylesheets.excludes" value=""/>
  +    <property name="forrest.validate.skins.stylesheets.failonerror"
  +      value="${forrest.validate.skins.failonerror}" />
  +  </target>
  +
  +
     <!-- Load properties from user's skinconf.xml, if it is defined -->
  -  <target name="load-project-props" depends="init-props" if="project.skinconf.present">
  +  <target name="load-project-props" depends="validation-props, validate-skinconf" if="skinconf.present">
       <xmlproperty file="${project.skinconf}" collapseattributes="true"
  -      validate="true"/>
  +      validate="${validate.skinconf}"/>
     </target>
   
     <!-- Load properties from Forrest's default skinconf.xml, unless a user's is defined -->
  -  <target name="load-forrest-props" depends="init-props" unless="project.skinconf.present">
  +  <target name="load-forrest-props" unless="skinconf.present">
       <xmlproperty file="${forrest.home}/context/skinconf.xml"
  -      collapseattributes="true" validate="true"/>
  +      collapseattributes="true" validate="true"/> <!-- Assume Forrest skinconf is valid -->
     </target>
   
     <!-- Define filters equating to elements in the skinconf.xml file. Skins can
  @@ -262,24 +350,10 @@
       copy-xdocs, copy-stylesheets, copy-images, copy-schema, copy-lib, 
       copy-classes, copy-skins, copy-skinconf, copy-status"/>
   
  -  <target name="project-context" depends="ensure-content, validate, init, bare-context, examine-proj, copy-conf, copy-sitemap,
  +  <target name="project-context" depends="examine-proj, ensure-content, validate, init, bare-context, copy-conf, copy-sitemap,
       copy-xdocs, copy-stylesheets, copy-images, copy-schema, copy-lib, 
       copy-classes, copy-skins, copy-skinconf, copy-status"/>
   
  -  <target name="examine-proj">
  -    <available property="conf.present" file="${project.conf-dir}" type="dir"/>
  -    <available property="sitemap.present" file="${project.sitemap}"/>
  -    <available property="xdocs.present" file="${project.xdocs-dir}" type="dir"/>
  -    <available property="images.present" file="${project.images-dir}" type="dir"/>
  -    <available property="schema.present" file="${project.schema-dir}" type="dir"/>
  -    <available property="stylesheets.present" file="${project.stylesheets-dir}" type="dir"/>
  -    <available property="lib.present" file="${project.lib-dir}" type="dir"/>
  -    <available property="classes.present" file="${project.classes-dir}" type="dir"/>
  -    <available property="skins.present" file="${project.skins-dir}" type="dir"/>
  -    <available property="skinconf.present" file="${project.skinconf}"/>
  -    <available property="status.present" file="${project.status}"/>
  -  </target>
  -
     <target name="copy-conf" if="conf.present">
       <copy toDir="${project.ctxt-dir}/WEB-INF" filtering="true"
         overwrite="true" failonerror="false">
  @@ -588,12 +662,14 @@
       </echo>
     </target>
   
  -  <!-- ===============================================================
  -       Validates all XML documents in the projects-context dir.
  -       =============================================================== -->
  - <target name="validate" depends="init-props, examine-proj"
  -   description="Validates XML doc files in the project">
  -   <xmlvalidate failonerror="${forrest.validate.failonerror}" lenient="no" warn="yes">
  +
  +
  +
  +  <target name="validate" depends="validation-props, validate-xdocs, validate-skins,
  +    validate-stylesheets"  description="Validates XML doc files in the project"/>
  +
  +  <target name="validate-xdocs" depends="validation-props" if="validate.xdocs">
  +    <xmlvalidate failonerror="${forrest.validate.xdocs.failonerror}" lenient="no" warn="yes">
         <xmlcatalog>
           <catalogfiles dir="${project.schema-dir}">
             <include name="catalog*"/>
  @@ -603,21 +679,42 @@
           </catalogfiles>
         </xmlcatalog>
         <fileset dir="${project.xdocs-dir}"
  -        includes="${forrest.validate.includes}"
  -        excludes="${forrest.validate.excludes}">
  -      </fileset>
  +        includes="${forrest.validate.xdocs.includes}"
  +        excludes="${forrest.validate.xdocs.excludes}"/>
       </xmlvalidate>
  -    <!-- validation of certain key files using RELAX NG -->
  -    <echo message=" "/>
  -    <echo message="Conducting RELAX NG validation of skinconf.xml"/>
  -    <taskdef name="jing" classname="com.thaiopensource.relaxng.util.JingTask">
  -     <classpath>
  -      <fileset dir="${forrest.home}/WEB-INF/lib" includes="*.jar" />
  -     </classpath>
  -    </taskdef>
  +    <echo message="...validated xdocs"/>
  +  </target>
  +
  +  <target name="validate-skinconf" depends="validation-props"
  +    if="validate.skinconf">
       <jing rngfile="${forrest.home}/context/resources/schema/relax/skinconf-v10.rng">
  -     <fileset dir="${project.content-dir}" includes="**/skinconf.xml"/>
  +      <fileset dir="${project.content-dir}"
  +        includes="forrest.validate.skinconf.includes"
  +        excludes="forrest.validate.skinconf.excludes"/>
  +    </jing>
  +    <echo message="...validated skinconf"/>
  +  </target>
  +
  +  <target name="validate-stylesheets" depends="validation-props"
  +    if="validate.stylesheets">
  +    <jing rngfile="${forrest.home}/context/resources/schema/relax/xslt.rng">
  +      <fileset dir="${project.stylesheets-dir}"
  +        includes="${forrest.validate.stylesheets.includes}"
  +        excludes="${forrest.validate.stylesheets.excludes}" />
  +    </jing>
  +    <echo message="...validated stylesheets"/>
  +  </target>
  +
  +  <target name="validate-skins" depends="validate-skins-stylesheets"/>
  +
  +  <target name="validate-skins-stylesheets" depends="validation-props"
  +    if="validate.skins.stylesheets">
  +    <jing rngfile="${forrest.home}/context/resources/schema/relax/xslt.rng">
  +      <fileset dir="${project.skins-dir}"
  +        includes="${forrest.validate.skins.stylesheets.includes}"
  +        excludes="${forrest.validate.skins.stylesheets.excludes}"/>
       </jing>
  +    <echo message="...validated skin stylesheets"/>
     </target>
   
   </project>
  
  
  
  1.9       +51 -6     xml-forrest/src/resources/fresh-site/forrest.properties
  
  Index: forrest.properties
  ===================================================================
  RCS file: /home/cvs/xml-forrest/src/resources/fresh-site/forrest.properties,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- forrest.properties	1 Nov 2002 06:52:17 -0000	1.8
  +++ forrest.properties	4 Nov 2002 09:13:05 -0000	1.9
  @@ -12,12 +12,9 @@
   #project.skin=basic
   #project.skin=forrest-site
   
  -# Should Forrest stop when an XML file is invalid?
  -#forrest.validate.failonerror=true
  -# Comma-separated list of path patterns to validate
  -#forrest.validate.includes=*.x*
  -# Comma-separated list of path patterns to not validate
  -#forrest.validate.excludes=
  +
  +##############
  +# layout properties
   
   # Properties that must be set to override the default locations
   #project.status=status.xml
  @@ -32,3 +29,51 @@
   #project.skinconf=${project.content-dir}/skinconf.xml
   #project.lib-dir=${project.content-dir}/lib
   #project.classes-dir=${project.content-dir}/classes
  +
  +
  +##############
  +# validation properties
  +
  +# These props determine if validation is performed at all
  +# Values are inherited unless overridden.
  +# Eg, if forrest.validate=false, then all others are false unless set to true.
  +#forrest.validate=true
  +#forrest.validate.xdocs=${forrest.validate}
  +#forrest.validate.skinconf=${forrest.validate}
  +#forrest.validate.stylesheets=${forrest.validate}
  +#forrest.validate.skins=${forrest.validate}
  +#forrest.validate.skins.stylesheets=${forrest.validate.skins}
  +
  +
  +# Key:
  +# *.failonerror=(true|false)    stop when an XML file is invalid
  +# *.includes=(pattern)         Comma-separated list of path patterns to validate
  +# *.excludes=(pattern)         Comma-separated list of path patterns to not validate
  +
  +#forrest.validate.includes=**/*
  +#forrest.validate.excludes=
  +#
  +#forrest.validate.xdocs.failonerror=${forrest.validate.failonerror}
  +#
  +#forrest.validate.xdocs.includes=*.x*
  +#forrest.validate.xdocs.excludes=
  +#
  +#forrest.validate.skinconf.includes=${skinconf-file}
  +#forrest.validate.skinconf.excludes=
  +#forrest.validate.skinconf.failonerror=${forrest.validate.failonerror}
  +#
  +#forrest.validate.skinconf.includes=${skinconf-file}
  +#forrest.validate.skinconf.excludes=
  +#forrest.validate.skinconf.failonerror=${forrest.validate.failonerror}
  +#
  +#forrest.validate.stylesheets.includes=**/*.xsl
  +#forrest.validate.stylesheets.excludes=
  +#forrest.validate.stylesheets.failonerror=${forrest.validate.failonerror}
  +#
  +#forrest.validate.skins.includes=**/*
  +#forrest.validate.skins.excludes=**/*.xsl
  +#forrest.validate.skins.failonerror=${forrest.validate.failonerror}
  +#
  +#forrest.validate.skins.stylesheets.includes=**/*.xsl
  +#forrest.validate.skins.stylesheets.excludes=
  +#forrest.validate.skins.stylesheets.failonerror=${forrest.validate.skins.failonerror}
  
  
  
  1.1                  xml-forrest/src/resources/schema/relax/xslt.rng
  
  Index: xslt.rng
  ===================================================================
  <?xml version="1.0" encoding="iso-8859-1"?>
  <!-- $Id: xslt.rng,v 1.1 2002/11/04 09:13:05 jefft Exp $ -->
  <!-- This was mostly generated from the syntax summary in the XSLT
       Recommendation (using XSLT of course). -->
  <!-- Issues: this validates extension elements as literal result
       elements, which is overly restrictive. -->
  <grammar xmlns="http://relaxng.org/ns/structure/1.0"
           ns="http://www.w3.org/1999/XSL/Transform"
           datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
     <start>
        <choice>
           <ref name="stylesheet.element"/>
           <ref name="transform.element"/>
           <ref name="literal-result-element-as-stylesheet"/>
        </choice>
     </start>
     <define name="version">
        <value>1.0</value>
     </define>
     <define name="top-level-elements.model">
        <zeroOrMore>
           <choice>
              <ref name="top-level-element.category"/>
              <ref name="top-level-extension"/>
           </choice>
        </zeroOrMore>
     </define>
     <define name="top-level-extension">
        <element>
           <anyName>
              <except>
                 <nsName/>
                 <nsName ns=""/>
              </except>
           </anyName>
           <grammar>
              <start>
                <ref name="any"/>
              </start>
              <define name="any">
  	       <zeroOrMore>
  		  <choice>
  		     <attribute>
  			<anyName/>
  		     </attribute>
  		     <text/>
  		     <element>
  			<anyName/>
  			<ref name="any"/>
  		     </element>
  		  </choice>
  	       </zeroOrMore>
              </define>
           </grammar>
        </element>
     </define>
     <define name="template.model">
        <zeroOrMore>
           <choice>
              <ref name="instruction.category"/>
              <ref name="literal-result-element"/>
              <text/>
           </choice>
        </zeroOrMore>
     </define>
     <define name="literal-result-element-as-stylesheet">
        <element>
           <anyName>
              <except>
                 <nsName/>
              </except>
           </anyName>
           <attribute>
              <name>version</name>
              <ref name="version"/>
           </attribute>
           <ref name="literal-result-element-no-version.atts"/>
           <ref name="template.model"/>
        </element>
     </define>
     <define name="literal-result-element">
        <element>
           <anyName>
              <except>
                 <nsName/>
              </except>
           </anyName>
           <ref name="literal-result-element.atts"/>
           <ref name="template.model"/>
        </element>
     </define>
     <define name="literal-result-element.atts">
        <ref name="literal-result-element-no-version.atts"/>
        <optional>
  	 <attribute>
  	    <name>version</name>
  	    <ref name="version"/>
  	 </attribute>
        </optional>
     </define>
     <define name="literal-result-element-no-version.atts">
        <zeroOrMore>
           <choice>
              <attribute>
  	       <anyName>
  		  <except>
  		     <nsName/>
  		  </except>
  	       </anyName>
                 <ref name="avt.datatype"/>
              </attribute>
              <attribute>
                 <name>extension-element-prefixes</name>
                 <ref name="prefixes.datatype"/>
  	    </attribute>
              <attribute>
                 <name>exclude-result-prefixes</name>
                 <ref name="prefixes.datatype"/>
  	    </attribute>
              <attribute>
                 <name>use-attribute-sets</name>
                 <ref name="qnames.datatype"/>
              </attribute>
           </choice>
        </zeroOrMore>
     </define>
     <define name="top-level-element.category">
        <choice>
           <ref name="include.element"/>
           <ref name="strip-space.element"/>
           <ref name="preserve-space.element"/>
           <ref name="template.element"/>
           <ref name="namespace-alias.element"/>
           <ref name="attribute-set.element"/>
           <ref name="variable.element"/>
           <ref name="param.element"/>
           <ref name="key.element"/>
           <ref name="decimal-format.element"/>
           <ref name="output.element"/>
        </choice>
     </define>
     <define name="instruction.category">
        <choice>
           <ref name="apply-templates.element"/>
           <ref name="apply-imports.element"/>
           <ref name="call-template.element"/>
           <ref name="element.element"/>
           <ref name="attribute.element"/>
           <ref name="text.element"/>
           <ref name="processing-instruction.element"/>
           <ref name="comment.element"/>
           <ref name="copy.element"/>
           <ref name="value-of.element"/>
           <ref name="number.element"/>
           <ref name="for-each.element"/>
           <ref name="if.element"/>
           <ref name="choose.element"/>
           <ref name="variable.element"/>
           <ref name="copy-of.element"/>
           <ref name="message.element"/>
           <ref name="fallback.element"/>
        </choice>
     </define>
     <define name="extension.atts">
        <zeroOrMore>
           <attribute>
              <anyName>
                 <except>
                    <nsName/>
                    <nsName ns=""/>
                 </except>
              </anyName>
           </attribute>
        </zeroOrMore>
     </define>
     <define name="stylesheet.element">
        <element name="stylesheet">
           <ref name="stylesheet.model"/>
        </element>
     </define>
     <define name="transform.element">
        <element name="transform">
           <ref name="stylesheet.model"/>
        </element>
     </define>
     <define name="stylesheet.model">
        <ref name="extension.atts"/>
        <optional>
  	 <attribute name="id">
  	    <data type="NCName"/>
  	 </attribute>
        </optional>
        <optional>
  	 <attribute name="extension-element-prefixes">
              <ref name="prefixes.datatype"/>
  	 </attribute>
        </optional>
        <optional>
  	 <attribute name="exclude-result-prefixes">
              <ref name="prefixes.datatype"/>
  	 </attribute>
        </optional>
        <attribute name="version">
  	 <ref name="version"/>
        </attribute>
        <group>
  	 <zeroOrMore>
  	    <ref name="import.element"/>
  	 </zeroOrMore>
  	 <ref name="top-level-elements.model"/>
        </group>
     </define>
     <define name="include.element">
        <element name="include">
           <ref name="extension.atts"/>
           <attribute name="href">
              <data type="anyURI"/>
           </attribute>
        </element>
     </define>
     <define name="import.element">
        <element name="import">
           <ref name="extension.atts"/>
           <attribute name="href">
              <data type="anyURI"/>
           </attribute>
        </element>
     </define>
     <define name="strip-space.element">
        <element name="strip-space">
           <ref name="extension.atts"/>
           <attribute name="elements">
              <ref name="wildcards.datatype"/>
           </attribute>
        </element>
     </define>
     <define name="preserve-space.element">
        <element name="preserve-space">
           <ref name="extension.atts"/>
           <attribute name="elements">
              <ref name="wildcards.datatype"/>
           </attribute>
        </element>
     </define>
     <define name="template.element">
        <element name="template">
           <ref name="extension.atts"/>
           <optional>
              <attribute name="match">
                 <ref name="pattern.datatype"/>
              </attribute>
           </optional>
           <optional>
              <attribute name="name">
                 <ref name="qname.datatype"/>
              </attribute>
           </optional>
           <optional>
              <attribute name="priority">
                 <ref name="number.datatype"/>
              </attribute>
           </optional>
           <optional>
              <attribute name="mode">
                 <ref name="qname.datatype"/>
              </attribute>
           </optional>
           <group>
              <zeroOrMore>
                 <ref name="param.element"/>
              </zeroOrMore>
              <ref name="template.model"/>
           </group>
        </element>
     </define>
     <define name="apply-templates.element">
        <element name="apply-templates">
           <ref name="extension.atts"/>
           <optional>
              <attribute name="select">
                 <ref name="expression.datatype"/>
              </attribute>
           </optional>
           <optional>
              <attribute name="mode">
                 <ref name="qname.datatype"/>
              </attribute>
           </optional>
           <zeroOrMore>
              <choice>
                 <ref name="sort.element"/>
                 <ref name="with-param.element"/>
              </choice>
           </zeroOrMore>
        </element>
     </define>
     <define name="apply-imports.element">
        <element name="apply-imports">
           <ref name="extension.atts"/>
        </element>
     </define>
     <define name="call-template.element">
        <element name="call-template">
           <ref name="extension.atts"/>
           <attribute name="name">
              <ref name="qname.datatype"/>
           </attribute>
           <zeroOrMore>
              <ref name="with-param.element"/>
           </zeroOrMore>
        </element>
     </define>
     <define name="namespace-alias.element">
        <element name="namespace-alias">
           <ref name="extension.atts"/>
           <attribute name="stylesheet-prefix">
              <ref name="prefix.datatype"/>
           </attribute>
           <attribute name="result-prefix">
              <ref name="prefix.datatype"/>
           </attribute>
        </element>
     </define>
     <define name="element.element">
        <element name="element">
           <ref name="extension.atts"/>
           <attribute name="name">
              <choice>
                 <ref name="qname.datatype"/>
                 <ref name="expr-avt.datatype"/>
              </choice>
           </attribute>
           <optional>
              <attribute name="namespace">
                 <choice>
                    <data type="anyURI"/>
                    <ref name="brace-avt.datatype"/>
                 </choice>
              </attribute>
           </optional>
           <optional>
              <attribute name="use-attribute-sets">
                 <ref name="qnames.datatype"/>
              </attribute>
           </optional>
           <ref name="template.model"/>
        </element>
     </define>
     <define name="attribute.element">
        <element name="attribute">
           <ref name="extension.atts"/>
           <attribute name="name">
              <choice>
                 <ref name="qname.datatype"/>
                 <ref name="expr-avt.datatype"/>
              </choice>
           </attribute>
           <optional>
              <attribute name="namespace">
                 <choice>
                    <data type="anyURI"/>
                    <ref name="brace-avt.datatype"/>
                 </choice>
              </attribute>
           </optional>
           <ref name="template.model"/>
        </element>
     </define>
     <define name="attribute-set.element">
        <element name="attribute-set">
           <ref name="extension.atts"/>
           <attribute name="name">
              <ref name="qname.datatype"/>
           </attribute>
           <optional>
              <attribute name="use-attribute-sets">
                 <ref name="qnames.datatype"/>
              </attribute>
           </optional>
           <zeroOrMore>
              <ref name="attribute.element"/>
           </zeroOrMore>
        </element>
     </define>
     <define name="text.element">
        <element name="text">
           <ref name="extension.atts"/>
           <optional>
              <attribute name="disable-output-escaping">
                 <choice>
                    <value type="string">yes</value>
                    <value type="string">no</value>
                 </choice>
              </attribute>
           </optional>
           <text/>
        </element>
     </define>
     <define name="processing-instruction.element">
        <element name="processing-instruction">
           <ref name="extension.atts"/>
           <attribute name="name">
              <choice>
                 <data type="NCName"/>
                 <ref name="expr-avt.datatype"/>
              </choice>
           </attribute>
           <ref name="template.model"/>
        </element>
     </define>
     <define name="comment.element">
        <element name="comment">
           <ref name="extension.atts"/>
           <ref name="template.model"/>
        </element>
     </define>
     <define name="copy.element">
        <element name="copy">
           <ref name="extension.atts"/>
           <optional>
              <attribute name="use-attribute-sets">
                 <ref name="qnames.datatype"/>
              </attribute>
           </optional>
           <ref name="template.model"/>
        </element>
     </define>
     <define name="value-of.element">
        <element name="value-of">
           <ref name="extension.atts"/>
           <attribute name="select">
              <ref name="expression.datatype"/>
           </attribute>
           <optional>
              <attribute name="disable-output-escaping">
                 <choice>
                    <value type="string">yes</value>
                    <value type="string">no</value>
                 </choice>
              </attribute>
           </optional>
        </element>
     </define>
     <define name="number.element">
        <element name="number">
           <ref name="extension.atts"/>
           <optional>
              <attribute name="level">
                 <choice>
                    <value type="string">single</value>
                    <value type="string">multiple</value>
                    <value type="string">any</value>
                 </choice>
              </attribute>
           </optional>
           <optional>
              <attribute name="count">
                 <ref name="pattern.datatype"/>
              </attribute>
           </optional>
           <optional>
              <attribute name="from">
                 <ref name="pattern.datatype"/>
              </attribute>
           </optional>
           <optional>
              <attribute name="value">
                 <ref name="expression.datatype"/>
              </attribute>
           </optional>
           <optional>
              <attribute name="format">
                 <ref name="avt.datatype"/>
              </attribute>
           </optional>
           <optional>
              <attribute name="lang">
                 <choice>
                    <data type="NMTOKEN"/>
                    <ref name="expr-avt.datatype"/>
                 </choice>
              </attribute>
           </optional>
           <optional>
              <attribute name="letter-value">
  	       <choice>
  		  <value type="string">alphabetic</value>
  		  <value type="string">traditional</value>
  		  <ref name="expr-avt.datatype"/>
  	       </choice>
              </attribute>
           </optional>
           <optional>
              <attribute name="grouping-separator">
                 <choice>
                    <ref name="char.datatype"/>
                    <ref name="expr-avt.datatype"/>
                 </choice>
              </attribute>
           </optional>
           <optional>
              <attribute name="grouping-size">
                 <choice>
                    <ref name="number.datatype"/>
                    <ref name="expr-avt.datatype"/>
                 </choice>
              </attribute>
           </optional>
        </element>
     </define>
     <define name="for-each.element">
        <element name="for-each">
           <ref name="extension.atts"/>
           <attribute name="select">
              <ref name="expression.datatype"/>
           </attribute>
           <group>
              <zeroOrMore>
                 <ref name="sort.element"/>
              </zeroOrMore>
              <ref name="template.model"/>
           </group>
        </element>
     </define>
     <define name="if.element">
        <element name="if">
           <ref name="extension.atts"/>
           <attribute name="test">
              <ref name="expression.datatype"/>
           </attribute>
           <ref name="template.model"/>
        </element>
     </define>
     <define name="choose.element">
        <element name="choose">
           <ref name="extension.atts"/>
           <group>
              <oneOrMore>
                 <ref name="when.element"/>
              </oneOrMore>
              <optional>
                 <ref name="otherwise.element"/>
              </optional>
           </group>
        </element>
     </define>
     <define name="when.element">
        <element name="when">
           <ref name="extension.atts"/>
           <attribute name="test">
              <ref name="expression.datatype"/>
           </attribute>
           <ref name="template.model"/>
        </element>
     </define>
     <define name="otherwise.element">
        <element name="otherwise">
           <ref name="extension.atts"/>
           <ref name="template.model"/>
        </element>
     </define>
     <define name="sort.element">
        <element name="sort">
           <ref name="extension.atts"/>
           <optional>
              <attribute name="select">
                 <ref name="expression.datatype"/>
              </attribute>
           </optional>
           <optional>
              <attribute name="lang">
                 <choice>
                    <data type="NMTOKEN"/>
                    <ref name="expr-avt.datatype"/>
                 </choice>
              </attribute>
           </optional>
           <optional>
              <attribute name="data-type">
  	       <choice>
  		  <value type="string">text</value>
  		  <value type="string">number</value>
  		  <ref name="qname-but-not-ncname.datatype"/>
  		  <ref name="expr-avt.datatype"/>
  	       </choice>
              </attribute>
           </optional>
           <optional>
              <attribute name="order">
  	       <choice>
  		  <value type="string">ascending</value>
  		  <value type="string">descending</value>
  		  <ref name="expr-avt.datatype"/>
  	       </choice>
              </attribute>
           </optional>
           <optional>
              <attribute name="case-order">
  	       <choice>
  		  <value type="string">upper-first</value>
  		  <value type="string">lower-first</value>
  		  <ref name="expr-avt.datatype"/>
  	       </choice>
              </attribute>
           </optional>
        </element>
     </define>
     <define name="variable.element">
        <element name="variable">
           <ref name="extension.atts"/>
           <attribute name="name">
              <ref name="qname.datatype"/>
           </attribute>
           <choice>
              <attribute name="select">
                 <ref name="expression.datatype"/>
              </attribute>
              <ref name="template.model"/>
           </choice>
        </element>
     </define>
     <define name="param.element">
        <element name="param">
           <ref name="extension.atts"/>
           <attribute name="name">
              <ref name="qname.datatype"/>
           </attribute>
           <choice>
              <attribute name="select">
                 <ref name="expression.datatype"/>
              </attribute>
              <ref name="template.model"/>
           </choice>
        </element>
     </define>
     <define name="copy-of.element">
        <element name="copy-of">
           <ref name="extension.atts"/>
           <attribute name="select">
              <ref name="expression.datatype"/>
           </attribute>
        </element>
     </define>
     <define name="with-param.element">
        <element name="with-param">
           <ref name="extension.atts"/>
           <attribute name="name">
              <ref name="qname.datatype"/>
           </attribute>
           <choice>
              <attribute name="select">
                 <ref name="expression.datatype"/>
              </attribute>
              <ref name="template.model"/>
           </choice>
        </element>
     </define>
     <define name="key.element">
        <element name="key">
           <ref name="extension.atts"/>
           <attribute name="name">
              <ref name="qname.datatype"/>
           </attribute>
           <attribute name="match">
              <ref name="pattern.datatype"/>
           </attribute>
           <attribute name="use">
              <ref name="expression.datatype"/>
           </attribute>
        </element>
     </define>
     <define name="decimal-format.element">
        <element name="decimal-format">
           <ref name="extension.atts"/>
           <optional>
              <attribute name="name">
                 <ref name="qname.datatype"/>
              </attribute>
           </optional>
           <optional>
              <attribute name="decimal-separator">
                 <ref name="char.datatype"/>
              </attribute>
           </optional>
           <optional>
              <attribute name="grouping-separator">
                 <ref name="char.datatype"/>
              </attribute>
           </optional>
           <optional>
              <attribute name="infinity">
                 <text/>
              </attribute>
           </optional>
           <optional>
              <attribute name="minus-sign">
                 <ref name="char.datatype"/>
              </attribute>
           </optional>
           <optional>
              <attribute name="NaN">
                 <text/>
              </attribute>
           </optional>
           <optional>
              <attribute name="percent">
                 <ref name="char.datatype"/>
              </attribute>
           </optional>
           <optional>
              <attribute name="per-mille">
                 <ref name="char.datatype"/>
              </attribute>
           </optional>
           <optional>
              <attribute name="zero-digit">
                 <ref name="char.datatype"/>
              </attribute>
           </optional>
           <optional>
              <attribute name="digit">
                 <ref name="char.datatype"/>
              </attribute>
           </optional>
           <optional>
              <attribute name="pattern-separator">
                 <ref name="char.datatype"/>
              </attribute>
           </optional>
        </element>
     </define>
     <define name="message.element">
        <element name="message">
           <ref name="extension.atts"/>
           <optional>
              <attribute name="terminate">
                 <choice>
                    <value type="string">yes</value>
                    <value type="string">no</value>
                 </choice>
              </attribute>
           </optional>
           <ref name="template.model"/>
        </element>
     </define>
     <define name="fallback.element">
        <element name="fallback">
           <ref name="extension.atts"/>
           <ref name="template.model"/>
        </element>
     </define>
     <define name="output.element">
        <element name="output">
           <ref name="extension.atts"/>
           <optional>
              <attribute name="method">
                 <choice>
                    <value type="string">xml</value>
                    <value type="string">html</value>
                    <value type="string">text</value>
                    <ref name="qname-but-not-ncname.datatype"/>
                 </choice>
              </attribute>
           </optional>
           <optional>
              <attribute name="version">
                 <data type="NMTOKEN"/>
              </attribute>
           </optional>
           <optional>
              <attribute name="encoding">
                 <text/>
              </attribute>
           </optional>
           <optional>
              <attribute name="omit-xml-declaration">
                 <choice>
                    <value type="string">yes</value>
                    <value type="string">no</value>
                 </choice>
              </attribute>
           </optional>
           <optional>
              <attribute name="standalone">
                 <choice>
                    <value type="string">yes</value>
                    <value type="string">no</value>
                 </choice>
              </attribute>
           </optional>
           <optional>
              <attribute name="doctype-public">
                 <text/>
              </attribute>
           </optional>
           <optional>
              <attribute name="doctype-system">
                 <text/>
              </attribute>
           </optional>
           <optional>
              <attribute name="cdata-section-elements">
                 <ref name="qnames.datatype"/>
              </attribute>
           </optional>
           <optional>
              <attribute name="indent">
                 <choice>
                    <value type="string">yes</value>
                    <value type="string">no</value>
                 </choice>
              </attribute>
           </optional>
           <optional>
              <attribute name="media-type">
                 <text/>
              </attribute>
           </optional>
        </element>
     </define>
     <define name="prefixes.datatype">
        <list>
           <zeroOrMore>
              <choice>
                 <data type="NCName"/>
                 <value>#default</value>
              </choice>
           </zeroOrMore>
        </list>
     </define>
     <define name="prefix.datatype">
        <choice>
  	 <data type="NCName"/>
  	 <value>#default</value>
        </choice>
     </define>
     <define name="wildcards.datatype">
        <list>
           <zeroOrMore>
  	    <choice>
  	       <data type="QName"/>
  	       <data type="token">
  		  <param name="pattern">\*|\i\c*:\*</param>
  	       </data>
  	    </choice>
           </zeroOrMore>
        </list> 
     </define>
     <define name="qname.datatype">
        <data type="QName"/>
     </define>
     <define name="qnames.datatype">
        <list>
           <zeroOrMore>
              <data type="QName"/>
           </zeroOrMore>
        </list>
     </define>
     <define name="char.datatype">
        <data type="string">
           <param name="length">1</param>
        </data>
     </define>
     <define name="number.datatype">
        <data type="decimal"/>
     </define>
     <define name="expression.datatype">
        <text/>
     </define>
     <define name="pattern.datatype">
        <text/>
     </define>
     <define name="qname-but-not-ncname.datatype">
        <data type="QName">
          <param name="pattern">.*:.*</param>
        </data>
     </define>
     <!-- An AVT containing at least one expression. -->
     <define name="expr-avt.datatype">
        <data type="string">
           <param name="pattern">([^\{\}]|\{\{|\}\})*\{([^&#34;'\{\}]|&#34;[^&#34;]*&#34;|'[^']*')+\}([^\{\}]|\{\{|\}\}|\{([^&#34;'\{\}]|&#34;[^&#34;]*&#34;|'[^']*')+\})*</param>
        </data>
     </define>
     <!-- An AVT containing at least one brace; ie where instantiated AVT
          is not the same as the literal AVT. -->
     <define name="brace-avt.datatype">
        <data type="string">
           <param name="pattern">[^\{\}]*(\{\{|\}\}|\{([^&#34;'\{\}]|&#34;[^&#34;]*&#34;|'[^']*')+\})([^\{\}]|\{\{|\}\}|\{([^&#34;'\{\}]|&#34;[^&#34;]*&#34;|'[^']*')+\})*</param>
        </data>
     </define>
     <define name="avt.datatype">
        <data type="string">
           <param name="pattern">([^\{\}]|\{\{|\}\}|\{([^&#34;'\{\}]|&#34;[^&#34;]*&#34;|'[^']*')+\})*</param>
        </data>
     </define>
  </grammar>