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[*/@expr]"> 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="@*|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:for-each select="element"> 59 <xsl:call-template name="process-element"/> 60 </xsl:for-each> 61 </xsl:element> 62 </axsl:template> 63 64 <!-- Make rules for nested elements. --> 65 <xsl:for-each select="element"> 66 <xsl:call-template name="process-rules"/> 67 </xsl:for-each> 68 69 </xsl:template> 70 71 72 73 <!-- Process elements. --> 74 75 <xsl:template name="process-element"> 76 <xsl:param name="path" select="@name"/> 77 78 <!-- Define elements which do not have selectors. --> 79 <xsl:variable name="adding-selectors" select="count(//selector[@element=current()/@name])"/> 80 81 <xsl:choose> 82 <!-- Enumerations. --> 83 <xsl:when test="@type='multiple-choice-value' or @type='multiple-choice-list-value'"> 84 <xsl:call-template name="inside-enumeration"> 85 <xsl:with-param name="path" select="$path"/> 86 </xsl:call-template> 87 </xsl:when> 88 <!-- Added elements. --> 89 <xsl:when test="$adding-selectors = 0"> 90 <xsl:element name="{@name}"> 91 <axsl:apply-templates select="{$path}/@*"/> 92 <xsl:for-each select="element"> 93 <xsl:call-template name="process-element"> 94 <xsl:with-param name="path" select="concat($path, '/', @name)"/> 95 </xsl:call-template> 96 </xsl:for-each> 97 </xsl:element> 98 </xsl:when> 99 <!-- Other elements are only added if found. --> 100 <xsl:otherwise> 101 <axsl:apply-templates select="{$path}"/> 102 </xsl:otherwise> 103 </xsl:choose> 104 </xsl:template> 105 106 107 108 <!-- Process rules. --> 109 110 <xsl:template name="process-rules"> 111 <xsl:param name="path" select="@name"/> 112 113 <!-- Define elements which do not have selectors. --> 114 <!-- NOTE: Duplicating adding-selectors - see above. --> 115 <xsl:variable name="adding-selectors" select="count(//selector[@element=current()/@name])"/> 116 117 <xsl:choose> 118 <xsl:when test="@type='multiple-choice-value' or @type='multiple-choice-list-value'"> 119 <!-- Do not match multiple-choice values. --> 120 </xsl:when> 121 <xsl:when test="$adding-selectors = 0"> 122 <xsl:for-each select="element"> 123 <xsl:call-template name="process-rules"> 124 <xsl:with-param name="path" select="concat($path, '/', @name)"/> 125 </xsl:call-template> 126 </xsl:for-each> 127 </xsl:when> 128 <xsl:otherwise> 129 <xsl:apply-templates select="."/> 130 </xsl:otherwise> 131 </xsl:choose> 132 </xsl:template> 133 134 135 136 <!-- Fill in enumerations. --> 137 138 <xsl:template name="inside-enumeration"> 139 <xsl:param name="path" select="@name"/> 140 141 <!-- Store multiple-choice selections, if appropriate. --> 142 <xsl:if test="../@type='multiple-choice-list'"> 143 <axsl:variable name="values-{@name}" select="{$path}/@{../attribute/@name}"/> 144 </xsl:if> 145 146 <axsl:for-each select="${../@name}/{../@name}/{@name}"> 147 <axsl:copy> 148 <axsl:apply-templates select="@*"/> 149 <xsl:if test="@type='multiple-choice-list-value'"> 150 <axsl:if test="$values-{@name}[string() = current()/@{attribute/@name}]"> 151 <axsl:attribute name="{@expr-name}">true</axsl:attribute> 152 </axsl:if> 153 </xsl:if> 154 </axsl:copy> 155 </axsl:for-each> 156 </xsl:template> 157 158 </xsl:stylesheet>