1 <?xml version="1.0"?> 2 <!-- 3 A stylesheet which takes lower-level template annotations and produces an output 4 stylesheet - something which is capable of transforming XML documents into Web 5 pages or other kinds of XML documents. 6 7 Copyright (C) 2005 Paul Boddie <paul@boddie.org.uk> 8 9 This library is free software; you can redistribute it and/or 10 modify it under the terms of the GNU Lesser General Public 11 License as published by the Free Software Foundation; either 12 version 2.1 of the License, or (at your option) any later version. 13 14 This library is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 Lesser General Public License for more details. 18 19 You should have received a copy of the GNU Lesser General Public 20 License along with this library; if not, write to the Free Software 21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 22 --> 23 <xsl:stylesheet version="1.0" 24 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 25 xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias" 26 xmlns:template="http://www.boddie.org.uk/ns/xmltools/template"> 27 28 <xsl:output indent="yes"/> 29 <xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/> 30 31 32 33 <!-- Match the document itself. --> 34 35 <xsl:template match="/"> 36 <axsl:stylesheet version="1.0"> 37 38 <axsl:output indent="yes"/> 39 <!-- NOTE: Hard-coded doctypes to hopefully satisfy JavaScript code. --> 40 <!-- doctype-public="-//W3C//DTD XHTML 1.1//EN" 41 doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" --> 42 43 <!-- Include internationalisation (i18n) support if appropriate. --> 44 <axsl:param name="translations"/> 45 <axsl:param name="locale"/> 46 47 <axsl:template match="/"> 48 49 <!-- Include the remaining attributes. --> 50 <xsl:apply-templates select="@*"/> 51 52 <!-- Process the elements. --> 53 <xsl:apply-templates select="*"/> 54 55 </axsl:template> 56 </axsl:stylesheet> 57 </xsl:template> 58 59 60 61 <!-- Match special conditional expression attributes. --> 62 63 <xsl:template match="*[@template:if]"> 64 <axsl:if test="{@template:if}"> 65 <xsl:choose> 66 <xsl:when test="@template:element"> 67 <xsl:call-template name="enter-element"> 68 <xsl:with-param name="other-elements" select="@template:element"/> 69 </xsl:call-template> 70 </xsl:when> 71 <xsl:otherwise> 72 <xsl:call-template name="enter-attribute"/> 73 </xsl:otherwise> 74 </xsl:choose> 75 </axsl:if> 76 </xsl:template> 77 78 79 80 <!-- Match element references. --> 81 82 <xsl:template match="*[not(@template:if) and @template:element]"> 83 <xsl:call-template name="enter-element"> 84 <xsl:with-param name="other-elements" select="@template:element"/> 85 </xsl:call-template> 86 </xsl:template> 87 88 <xsl:template name="enter-element"> 89 <xsl:param name="other-elements"/> 90 <xsl:variable name="first-element" select="substring-before($other-elements, ',')"/> 91 <xsl:variable name="remaining-elements" select="substring-after($other-elements, ',')"/> 92 <xsl:choose> 93 <xsl:when test="$first-element = ''"> 94 <xsl:call-template name="next-element"> 95 <xsl:with-param name="first-element" select="$other-elements"/> 96 </xsl:call-template> 97 </xsl:when> 98 <xsl:otherwise> 99 <xsl:call-template name="next-element"> 100 <xsl:with-param name="first-element" select="$first-element"/> 101 <xsl:with-param name="remaining-elements" select="$remaining-elements"/> 102 </xsl:call-template> 103 </xsl:otherwise> 104 </xsl:choose> 105 </xsl:template> 106 107 <xsl:template name="next-element"> 108 <xsl:param name="first-element"/> 109 <xsl:param name="remaining-elements"/> 110 <axsl:for-each select="{$first-element}"> 111 <xsl:choose> 112 <xsl:when test="$remaining-elements = ''"> 113 <xsl:call-template name="enter-attribute"/> 114 </xsl:when> 115 <xsl:otherwise> 116 <xsl:call-template name="enter-element"> 117 <xsl:with-param name="other-elements" select="$remaining-elements"/> 118 </xsl:call-template> 119 </xsl:otherwise> 120 </xsl:choose> 121 </axsl:for-each> 122 </xsl:template> 123 124 125 126 <!-- Match special expression attributes. --> 127 128 <xsl:template match="*[not(@template:if) and not(@template:element) and (@template:attribute or @template:value or @template:expr or @template:copy)]"> 129 <xsl:call-template name="enter-attribute"/> 130 </xsl:template> 131 132 <xsl:template name="enter-attribute"> 133 <xsl:choose> 134 <xsl:when test="@template:attribute"> 135 <axsl:choose> 136 <axsl:when test="@{@template:attribute}"> 137 <axsl:variable name="this-name"><xsl:value-of select="@template:attribute"/></axsl:variable> 138 <axsl:variable name="this-value" select="@{@template:attribute}"/> 139 <xsl:call-template name="special-attributes"/> 140 </axsl:when> 141 <axsl:otherwise> 142 <axsl:variable name="this-name"><xsl:value-of select="@template:attribute"/></axsl:variable> 143 <axsl:variable name="this-value"></axsl:variable> 144 <xsl:call-template name="special-attributes"/> 145 </axsl:otherwise> 146 </axsl:choose> 147 </xsl:when> 148 <xsl:otherwise> 149 <xsl:call-template name="special-attributes"/> 150 </xsl:otherwise> 151 </xsl:choose> 152 </xsl:template> 153 154 <xsl:template name="special-attributes"> 155 <xsl:choose> 156 <xsl:when test="@template:effect = 'replace'"> 157 <xsl:call-template name="special-value"/> 158 </xsl:when> 159 <xsl:otherwise> 160 <xsl:copy> 161 <xsl:apply-templates select="@*"/> 162 <xsl:call-template name="expression-attributes"/> 163 </xsl:copy> 164 </xsl:otherwise> 165 </xsl:choose> 166 </xsl:template> 167 168 <xsl:template name="expression-attributes"> 169 <xsl:if test="@template:expr and @template:expr-attr"> 170 <axsl:if test="{@template:expr}"> 171 <axsl:attribute name="{@template:expr-attr}"><xsl:value-of select="@template:expr-attr"/></axsl:attribute> 172 </axsl:if> 173 </xsl:if> 174 <xsl:call-template name="special-value"/> 175 </xsl:template> 176 177 <xsl:template name="special-value"> 178 <xsl:choose> 179 <!-- Insert the stated value. --> 180 <xsl:when test="@template:value"> 181 <axsl:value-of select="{@template:value}"/> 182 </xsl:when> 183 <!-- Insert the translated value. --> 184 <xsl:when test="@template:i18n"> 185 <xsl:call-template name="translated-value"/> 186 </xsl:when> 187 <!-- Copy the stated expression. --> 188 <xsl:when test="@template:copy"> 189 <axsl:copy-of select="{@template:copy}"/> 190 </xsl:when> 191 <!-- Just process the descendants. --> 192 <xsl:otherwise> 193 <xsl:apply-templates select="node()"/> 194 </xsl:otherwise> 195 </xsl:choose> 196 </xsl:template> 197 198 199 200 <!-- Match internationalisation attributes. --> 201 202 <xsl:template match="*[not(@template:if) and not(@template:element) and not(@template:attribute) and not(@template:value) and not(@template:expr) and @template:i18n]"> 203 <xsl:copy> 204 <xsl:apply-templates select="@*"/> 205 <xsl:call-template name="translated-value"/> 206 </xsl:copy> 207 </xsl:template> 208 209 <xsl:template name="translated-value"> 210 <xsl:choose> 211 <!-- Look for a translation of the contents. --> 212 <xsl:when test="@template:i18n = '-'"> 213 <!-- NOTE: Quoting not done completely. --> 214 <axsl:variable name="translation" 215 select="$translations/translations/locale[code/@value=$locale]/translation[@value='{text()}']/text()"/> 216 <xsl:call-template name="insert-translated-value"/> 217 </xsl:when> 218 <!-- Look for a named translation. --> 219 <xsl:otherwise> 220 <!-- NOTE: Quoting not done completely. --> 221 <axsl:variable name="translation" 222 select="$translations/translations/locale[code/@value=$locale]/translation[@value='{@template:i18n}']/text()"/> 223 <xsl:call-template name="insert-translated-value"/> 224 </xsl:otherwise> 225 </xsl:choose> 226 </xsl:template> 227 228 <xsl:template name="insert-translated-value"> 229 <axsl:choose> 230 <!-- Insert the translated value. --> 231 <axsl:when test="$translation"> 232 <axsl:value-of select="$translation"/> 233 </axsl:when> 234 <!-- Otherwise, just process the descendants. --> 235 <axsl:otherwise> 236 <xsl:apply-templates select="node()"/> 237 </axsl:otherwise> 238 </axsl:choose> 239 </xsl:template> 240 241 242 243 <!-- Remove template attributes. --> 244 245 <xsl:template match="@template:element|@template:init|@template:attribute|@template:value|@template:expr|@template:expr-attr|@template:effect|@template:if|@template:i18n"> 246 </xsl:template> 247 248 249 250 <!-- Replicate unknown elements. --> 251 252 <xsl:template match="@*|node()"> 253 <xsl:copy> 254 <xsl:apply-templates select="@*|node()"/> 255 </xsl:copy> 256 </xsl:template> 257 258 </xsl:stylesheet>