1.1 --- a/XSLForms/XSL/Prepare.xsl Fri Jan 27 00:35:15 2006 +0000
1.2 +++ b/XSLForms/XSL/Prepare.xsl Fri Jan 27 00:40:56 2006 +0000
1.3 @@ -23,109 +23,158 @@
1.4 <xsl:stylesheet version="1.0"
1.5 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
1.6 xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias"
1.7 - xmlns:template="http://www.boddie.org.uk/ns/xmltools/template">
1.8 + xmlns:template="http://www.boddie.org.uk/ns/xmltools/template"
1.9 + xmlns:str="http://exslt.org/strings"
1.10 + extension-element-prefixes="str">
1.11
1.12 <xsl:output indent="yes"/>
1.13 <xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
1.14
1.15 -
1.16 + <!-- Fragment extraction support. -->
1.17 + <xsl:param name="element-id"/>
1.18
1.19 <!-- Match the document itself. -->
1.20
1.21 <xsl:template match="/">
1.22 - <axsl:stylesheet version="1.0">
1.23 + <axsl:stylesheet version="1.0"
1.24 + xmlns:dyn="http://exslt.org/dynamic"
1.25 + extension-element-prefixes="dyn">
1.26
1.27 <axsl:output indent="yes"/>
1.28 - <!-- NOTE: Hard-coded doctypes to hopefully satisfy JavaScript code. -->
1.29 - <!-- doctype-public="-//W3C//DTD XHTML 1.1//EN"
1.30 - doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" -->
1.31
1.32 <!-- Include internationalisation (i18n) support if appropriate. -->
1.33 <axsl:param name="translations"/>
1.34 <axsl:param name="locale"/>
1.35
1.36 + <!-- Include fragment support if appropriate. -->
1.37 + <axsl:param name="element-path"/>
1.38 +
1.39 <axsl:template match="/">
1.40 + <xsl:choose>
1.41 + <!-- Fragment production. -->
1.42 + <xsl:when test="$element-id != ''">
1.43 + <axsl:for-each select="dyn:evaluate($element-path)">
1.44 + <xsl:apply-templates select="@*|node()"/>
1.45 + </axsl:for-each>
1.46 + </xsl:when>
1.47 + <!-- Whole template production. -->
1.48 + <xsl:otherwise>
1.49 + <xsl:apply-templates select="@*|node()"/>
1.50 + </xsl:otherwise>
1.51 + </xsl:choose>
1.52 + </axsl:template>
1.53
1.54 - <!-- Include the remaining attributes. -->
1.55 - <xsl:apply-templates select="@*"/>
1.56 + <!-- Produce the rules for each element. -->
1.57 +
1.58 + <xsl:apply-templates select="//*[@template:element]">
1.59 + <xsl:with-param name="top-level">true</xsl:with-param>
1.60 + </xsl:apply-templates>
1.61 +
1.62 + </axsl:stylesheet>
1.63 + </xsl:template>
1.64 +
1.65 +
1.66 +
1.67 + <!-- Match elements referencing elements. -->
1.68 +
1.69 + <xsl:template match="*[@template:element]" priority="1">
1.70 + <xsl:param name="top-level">false</xsl:param>
1.71 + <xsl:call-template name="enter-element">
1.72 + <xsl:with-param name="top-level" select="$top-level"/>
1.73 + </xsl:call-template>
1.74 + </xsl:template>
1.75
1.76 - <!-- Process the elements. -->
1.77 - <xsl:apply-templates select="*"/>
1.78 + <xsl:template name="enter-element">
1.79 + <xsl:param name="top-level"/>
1.80 + <xsl:choose>
1.81 + <!-- Produce templates where this is a top-level definition. -->
1.82 + <xsl:when test="$top-level = 'true'">
1.83 + <xsl:call-template name="element-template">
1.84 + <xsl:with-param name="element-names" select="@template:element"/>
1.85 + </xsl:call-template>
1.86 + </xsl:when>
1.87 + <!-- Produce references to elements where this is within a template. -->
1.88 + <xsl:otherwise>
1.89 + <xsl:variable name="first-name" select="str:split(@template:element, ',')[1]"/>
1.90 + <!-- Check to see if this is a recursive reference. -->
1.91 + <xsl:variable name="recursive-element" select="ancestor::*[$first-name = str:split(@template:element, ',')[1]]"/>
1.92 + <xsl:choose>
1.93 + <!-- Generate a reference to the previous element definition. -->
1.94 + <xsl:when test="$recursive-element">
1.95 + <axsl:apply-templates select="{$first-name}" mode="{generate-id($recursive-element)}"/>
1.96 + </xsl:when>
1.97 + <!-- Generate a reference to this element definition. -->
1.98 + <xsl:otherwise>
1.99 + <axsl:apply-templates select="{$first-name}" mode="{generate-id(.)}"/>
1.100 + </xsl:otherwise>
1.101 + </xsl:choose>
1.102 + </xsl:otherwise>
1.103 + </xsl:choose>
1.104 + </xsl:template>
1.105
1.106 - </axsl:template>
1.107 - </axsl:stylesheet>
1.108 + <xsl:template name="element-template">
1.109 + <xsl:param name="element-names"/>
1.110 + <xsl:variable name="this-name" select="substring-before($element-names, ',')"/>
1.111 + <xsl:variable name="next-names" select="substring-after($element-names, ',')"/>
1.112 + <xsl:variable name="next-name" select="str:split($next-names, ',')[1]"/>
1.113 + <xsl:choose>
1.114 + <!-- Non-last part of a list of element names. -->
1.115 + <!-- Produce a template referencing another template. -->
1.116 + <xsl:when test="$this-name != ''">
1.117 + <!-- Produce a template with a mode. -->
1.118 + <axsl:template match="{$this-name}" mode="{generate-id(.)}">
1.119 + <axsl:apply-templates select="{$next-name}" mode="{generate-id(.)}"/>
1.120 + </axsl:template>
1.121 + <!-- Produce the other elements' templates... -->
1.122 + <xsl:call-template name="element-template">
1.123 + <xsl:with-param name="element-names" select="$next-names"/>
1.124 + </xsl:call-template>
1.125 + </xsl:when>
1.126 + <!-- Last part of a list of element names. -->
1.127 + <!-- Produce a template with content. -->
1.128 + <xsl:otherwise>
1.129 + <!-- Produce a template with a mode. -->
1.130 + <axsl:template match="{$element-names}" mode="{generate-id(.)}">
1.131 + <xsl:call-template name="enter-attribute"/>
1.132 + </axsl:template>
1.133 + </xsl:otherwise>
1.134 + </xsl:choose>
1.135 </xsl:template>
1.136
1.137
1.138
1.139 <!-- Match special conditional expression attributes. -->
1.140
1.141 - <xsl:template match="*[@template:if]">
1.142 - <axsl:if test="{@template:if}">
1.143 - <xsl:choose>
1.144 - <xsl:when test="@template:element">
1.145 - <xsl:call-template name="enter-element">
1.146 - <xsl:with-param name="other-elements" select="@template:element"/>
1.147 - </xsl:call-template>
1.148 - </xsl:when>
1.149 - <xsl:otherwise>
1.150 - <xsl:call-template name="enter-attribute"/>
1.151 - </xsl:otherwise>
1.152 - </xsl:choose>
1.153 - </axsl:if>
1.154 - </xsl:template>
1.155 -
1.156 -
1.157 -
1.158 - <!-- Match element references. -->
1.159 -
1.160 - <xsl:template match="*[not(@template:if) and @template:element]">
1.161 - <xsl:call-template name="enter-element">
1.162 - <xsl:with-param name="other-elements" select="@template:element"/>
1.163 - </xsl:call-template>
1.164 - </xsl:template>
1.165 -
1.166 - <xsl:template name="enter-element">
1.167 - <xsl:param name="other-elements"/>
1.168 - <xsl:variable name="first-element" select="substring-before($other-elements, ',')"/>
1.169 - <xsl:variable name="remaining-elements" select="substring-after($other-elements, ',')"/>
1.170 + <xsl:template match="*[@template:if]" priority="2">
1.171 + <xsl:param name="top-level">false</xsl:param>
1.172 <xsl:choose>
1.173 - <xsl:when test="$first-element = ''">
1.174 - <xsl:call-template name="next-element">
1.175 - <xsl:with-param name="first-element" select="$other-elements"/>
1.176 + <!-- Since this rule may be invoked at the top level, ignore conditions. -->
1.177 + <xsl:when test="$top-level = 'true'">
1.178 + <xsl:call-template name="enter-element">
1.179 + <xsl:with-param name="top-level" select="$top-level"/>
1.180 </xsl:call-template>
1.181 </xsl:when>
1.182 + <!-- As part of a template, generate the condition. -->
1.183 <xsl:otherwise>
1.184 - <xsl:call-template name="next-element">
1.185 - <xsl:with-param name="first-element" select="$first-element"/>
1.186 - <xsl:with-param name="remaining-elements" select="$remaining-elements"/>
1.187 - </xsl:call-template>
1.188 + <axsl:if test="{@template:if}">
1.189 + <xsl:choose>
1.190 + <xsl:when test="@template:element">
1.191 + <xsl:call-template name="enter-element"/>
1.192 + </xsl:when>
1.193 + <xsl:otherwise>
1.194 + <xsl:call-template name="enter-attribute"/>
1.195 + </xsl:otherwise>
1.196 + </xsl:choose>
1.197 + </axsl:if>
1.198 </xsl:otherwise>
1.199 </xsl:choose>
1.200 </xsl:template>
1.201
1.202 - <xsl:template name="next-element">
1.203 - <xsl:param name="first-element"/>
1.204 - <xsl:param name="remaining-elements"/>
1.205 - <axsl:for-each select="{$first-element}">
1.206 - <xsl:choose>
1.207 - <xsl:when test="$remaining-elements = ''">
1.208 - <xsl:call-template name="enter-attribute"/>
1.209 - </xsl:when>
1.210 - <xsl:otherwise>
1.211 - <xsl:call-template name="enter-element">
1.212 - <xsl:with-param name="other-elements" select="$remaining-elements"/>
1.213 - </xsl:call-template>
1.214 - </xsl:otherwise>
1.215 - </xsl:choose>
1.216 - </axsl:for-each>
1.217 - </xsl:template>
1.218 -
1.219
1.220
1.221 <!-- Match special expression attributes. -->
1.222
1.223 - <xsl:template match="*[not(@template:if) and not(@template:element) and (@template:attribute or @template:value or @template:expr or @template:copy)]">
1.224 + <xsl:template match="*[@template:attribute or @template:value or @template:expr or @template:copy]">
1.225 <xsl:call-template name="enter-attribute"/>
1.226 </xsl:template>
1.227
1.228 @@ -242,7 +291,7 @@
1.229
1.230 <!-- Remove template attributes. -->
1.231
1.232 - <xsl:template match="@template:element|@template:init|@template:attribute|@template:value|@template:expr|@template:expr-attr|@template:effect|@template:if|@template:i18n">
1.233 + <xsl:template match="@template:element|@template:init|@template:attribute|@template:value|@template:expr|@template:expr-attr|@template:effect|@template:if|@template:i18n|@template:copy">
1.234 </xsl:template>
1.235
1.236