1 <?xml version="1.0"?> 2 <xsl:stylesheet version="1.0" 3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 4 xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias" 5 xmlns:template="http://www.boddie.org.uk/ns/xmltools/template"> 6 7 <xsl:output indent="yes"/> 8 <xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/> 9 10 11 12 <!-- Match the document itself. --> 13 14 <xsl:template match="/"> 15 <axsl:stylesheet version="1.0"> 16 17 <axsl:output indent="yes"/> 18 19 <!-- Make document parameters for all elements appearing to use enumerations. --> 20 <xsl:for-each select="//element[@type='multiple-choice' or @type='multiple-choice-list']"> 21 <axsl:param name="{@name}"/> 22 </xsl:for-each> 23 24 <!-- Make a document-level rule. --> 25 <axsl:template match="/"> 26 <axsl:apply-templates select="*"/> 27 </axsl:template> 28 29 <!-- Process the top-level element to make other rules. --> 30 <xsl:apply-templates select="*"/> 31 32 <!-- Replicate unknown elements. --> 33 <axsl:template match="@*|placeholder|node()"> 34 <axsl:copy> 35 <axsl:apply-templates select="@*|node()"/> 36 </axsl:copy> 37 </axsl:template> 38 39 </axsl:stylesheet> 40 </xsl:template> 41 42 43 44 <!-- Match element references. --> 45 46 <xsl:template match="element"> 47 48 <!-- Make a rule for the element. --> 49 <axsl:template match="{@name}"> 50 51 <!-- Copy the element. --> 52 <xsl:element name="{@name}"> 53 54 <!-- Process attributes. --> 55 <axsl:apply-templates select="@*"/> 56 57 <!-- Find elements and determine how to process them. --> 58 <xsl:call-template name="process-elements"/> 59 </xsl:element> 60 </axsl:template> 61 62 <!-- Make rules for nested elements. --> 63 <xsl:call-template name="process-rules"/> 64 65 </xsl:template> 66 67 68 69 <!-- Process elements. --> 70 71 <xsl:template name="process-elements"> 72 <xsl:param name="path">.</xsl:param> 73 74 <xsl:for-each select="element"> 75 <!-- Define elements which do not have selectors. --> 76 <xsl:variable name="adding-selectors" select="count(//selector[@element=current()/@name])"/> 77 78 <xsl:choose> 79 <!-- Enumerations. --> 80 <xsl:when test="@type='multiple-choice-value' or @type='multiple-choice-list-value'"> 81 <xsl:call-template name="inside-enumeration"> 82 <xsl:with-param name="path" select="concat($path, '/', @name)"/> 83 </xsl:call-template> 84 </xsl:when> 85 <!-- Added elements. --> 86 <xsl:when test="$adding-selectors = 0"> 87 <xsl:element name="{@name}"> 88 <axsl:apply-templates select="{$path}/{@name}/@*"/> 89 <xsl:call-template name="process-elements"> 90 <xsl:with-param name="path" select="concat($path, '/', @name)"/> 91 </xsl:call-template> 92 </xsl:element> 93 </xsl:when> 94 <!-- Other elements are only added if found. --> 95 <xsl:otherwise> 96 <axsl:apply-templates select="{$path}/{@name}|{$path}/placeholder"/> 97 </xsl:otherwise> 98 </xsl:choose> 99 </xsl:for-each> 100 </xsl:template> 101 102 103 104 <!-- Process rules. --> 105 106 <xsl:template name="process-rules"> 107 <xsl:param name="path">.</xsl:param> 108 109 <xsl:for-each select="element"> 110 <!-- Define elements which do not have selectors. --> 111 <!-- NOTE: Duplicating adding-selectors - see above. --> 112 <xsl:variable name="adding-selectors" select="count(//selector[@element=current()/@name])"/> 113 114 <xsl:choose> 115 <xsl:when test="@type='multiple-choice-value' or @type='multiple-choice-list-value'"> 116 <!-- Do not match multiple-choice values. --> 117 </xsl:when> 118 <xsl:when test="$adding-selectors = 0"> 119 <xsl:call-template name="process-rules"> 120 <xsl:with-param name="path" select="concat($path, '/', @name)"/> 121 </xsl:call-template> 122 </xsl:when> 123 <xsl:otherwise> 124 <xsl:apply-templates select="."/> 125 </xsl:otherwise> 126 </xsl:choose> 127 </xsl:for-each> 128 </xsl:template> 129 130 131 132 <!-- Fill in enumerations. --> 133 134 <xsl:template name="inside-enumeration"> 135 <xsl:param name="path"/> 136 137 <!-- Store multiple-choice selections, if appropriate. --> 138 <xsl:if test="../@type='multiple-choice-list'"> 139 <axsl:variable name="values-{@name}" select="{$path}/@{../attribute/@name}"/> 140 </xsl:if> 141 142 <axsl:for-each select="${../@name}/{../@name}/{@name}"> 143 <axsl:copy> 144 <axsl:apply-templates select="@*"/> 145 <xsl:if test="@type='multiple-choice-list-value'"> 146 <axsl:if test="$values-{@name}[string() = current()/@{attribute/@name}]"> 147 <axsl:attribute name="{@expr-name}">true</axsl:attribute> 148 </axsl:if> 149 </xsl:if> 150 </axsl:copy> 151 </axsl:for-each> 152 </xsl:template> 153 154 </xsl:stylesheet>