1 <?xml version="1.0"?> 2 <!-- 3 Copyright (C) 2005 Paul Boddie <paul@boddie.org.uk> 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 --> 19 <xsl:stylesheet version="1.0" 20 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 21 xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias" 22 xmlns:template="http://www.boddie.org.uk/ns/xmltools/template"> 23 24 <xsl:output indent="yes"/> 25 <xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/> 26 27 28 29 <!-- Match the document itself. --> 30 31 <xsl:template match="/"> 32 <axsl:stylesheet version="1.0"> 33 34 <axsl:output indent="yes"/> 35 36 <!-- Make document parameters for all elements appearing to use enumerations. --> 37 <xsl:for-each select="//element[@type='multiple-choice' or @type='multiple-choice-list']"> 38 <axsl:param name="{@name}"/> 39 </xsl:for-each> 40 41 <!-- Make a document-level rule. --> 42 <axsl:template match="/"> 43 <axsl:apply-templates select="*"/> 44 </axsl:template> 45 46 <!-- Process the top-level element to make other rules. --> 47 <xsl:apply-templates select="*"/> 48 49 <!-- Replicate unknown elements. --> 50 <axsl:template match="@*|placeholder|node()"> 51 <axsl:copy> 52 <axsl:apply-templates select="@*|node()"/> 53 </axsl:copy> 54 </axsl:template> 55 56 </axsl:stylesheet> 57 </xsl:template> 58 59 60 61 <!-- Match element references. --> 62 63 <xsl:template match="element"> 64 65 <!-- Make a rule for the element. --> 66 <axsl:template match="{@name}"> 67 68 <!-- Copy the element. --> 69 <xsl:element name="{@name}"> 70 71 <!-- Process attributes. --> 72 <axsl:apply-templates select="@*"/> 73 74 <!-- Find elements and determine how to process them. --> 75 <xsl:call-template name="process-elements"/> 76 </xsl:element> 77 </axsl:template> 78 79 <!-- Make rules for nested elements. --> 80 <xsl:call-template name="process-rules"/> 81 82 </xsl:template> 83 84 85 86 <!-- Process elements. --> 87 88 <xsl:template name="process-elements"> 89 <xsl:param name="path">.</xsl:param> 90 91 <xsl:for-each select="element"> 92 <!-- Define elements which do not have selectors. --> 93 <xsl:variable name="adding-selectors" select="count(//selector[@element=current()/@name])"/> 94 95 <xsl:choose> 96 <!-- Enumerations. --> 97 <xsl:when test="@type='multiple-choice-value' or @type='multiple-choice-list-value'"> 98 <xsl:call-template name="inside-enumeration"> 99 <xsl:with-param name="path" select="concat($path, '/', @name)"/> 100 </xsl:call-template> 101 </xsl:when> 102 <!-- Added elements. --> 103 <xsl:when test="$adding-selectors = 0"> 104 <xsl:element name="{@name}"> 105 <axsl:apply-templates select="{$path}/{@name}/@*"/> 106 <xsl:call-template name="process-elements"> 107 <xsl:with-param name="path" select="concat($path, '/', @name)"/> 108 </xsl:call-template> 109 </xsl:element> 110 </xsl:when> 111 <!-- Other elements are only added if found. --> 112 <xsl:otherwise> 113 <axsl:apply-templates select="{$path}/{@name}|{$path}/placeholder"/> 114 </xsl:otherwise> 115 </xsl:choose> 116 </xsl:for-each> 117 </xsl:template> 118 119 120 121 <!-- Process rules. --> 122 123 <xsl:template name="process-rules"> 124 <xsl:param name="path">.</xsl:param> 125 126 <xsl:for-each select="element"> 127 <!-- Define elements which do not have selectors. --> 128 <!-- NOTE: Duplicating adding-selectors - see above. --> 129 <xsl:variable name="adding-selectors" select="count(//selector[@element=current()/@name])"/> 130 131 <xsl:choose> 132 <xsl:when test="@type='multiple-choice-value' or @type='multiple-choice-list-value'"> 133 <!-- Do not match multiple-choice values. --> 134 </xsl:when> 135 <xsl:when test="$adding-selectors = 0"> 136 <xsl:call-template name="process-rules"> 137 <xsl:with-param name="path" select="concat($path, '/', @name)"/> 138 </xsl:call-template> 139 </xsl:when> 140 <xsl:otherwise> 141 <xsl:apply-templates select="."/> 142 </xsl:otherwise> 143 </xsl:choose> 144 </xsl:for-each> 145 </xsl:template> 146 147 148 149 <!-- Fill in enumerations. --> 150 151 <xsl:template name="inside-enumeration"> 152 <xsl:param name="path"/> 153 154 <!-- Store multiple-choice selections, if appropriate. --> 155 <xsl:if test="../@type='multiple-choice-list'"> 156 <!-- NOTE: It is assumed here that ../attribute/@name (if it exists) == attribute/@name. --> 157 <axsl:variable name="values-{@name}" select="{$path}/@{attribute/@name}"/> 158 </xsl:if> 159 160 <!-- Select inside the enumeration source, inside an element with the field's name, the enumeration elements. --> 161 <axsl:for-each select="${../@name}/{../@name}/{@name}"> 162 <axsl:copy> 163 <axsl:apply-templates select="@*"/> 164 <xsl:if test="@type='multiple-choice-list-value'"> 165 <axsl:if test="$values-{@name}[string() = current()/@{attribute/@name}]"> 166 <axsl:attribute name="{@expr-name}">true</axsl:attribute> 167 </axsl:if> 168 </xsl:if> 169 </axsl:copy> 170 </axsl:for-each> 171 </xsl:template> 172 173 </xsl:stylesheet>