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">([^\{\}]|\{\{|\}\})*\{([^"'\{\}]|"[^"]*"|'[^']*')+\}([^\{\}]|\{\{|\}\}|\{([^"'\{\}]|"[^"]*"|'[^']*')+\})*</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">[^\{\}]*(\{\{|\}\}|\{([^"'\{\}]|"[^"]*"|'[^']*')+\})([^\{\}]|\{\{|\}\}|\{([^"'\{\}]|"[^"]*"|'[^']*')+\})*</param>
</data>
</define>
<define name="avt.datatype">
<data type="string">
<param name="pattern">([^\{\}]|\{\{|\}\}|\{([^"'\{\}]|"[^"]*"|'[^']*')+\})*</param>
</data>
</define>
</grammar>