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 <!-- Store multiple-choice selections, if appropriate. --> 79 <xsl:if test="@type='multiple-choice-list'"> 80 <axsl:variable name="values" select="{@name}/{element[@type='multiple-choice-list-value']/@name}/@{attribute/@name}"/> 81 </xsl:if> 82 83 <!-- Define elements which do not have selectors. --> 84 <xsl:variable name="adding-selectors" select="count(//selector[@element=current()/@name])"/> 85 86 <xsl:choose> 87 <!-- Enumerations. --> 88 <xsl:when test="@type='multiple-choice-value' or @type='multiple-choice-list-value'"> 89 <xsl:call-template name="inside-enumeration"/> 90 </xsl:when> 91 <!-- Added elements. --> 92 <xsl:when test="$adding-selectors = 0"> 93 <xsl:element name="{@name}"> 94 <axsl:apply-templates select="{$path}/@*"/> 95 <xsl:for-each select="element"> 96 <xsl:call-template name="process-element"> 97 <xsl:with-param name="path" select="concat($path, '/', @name)"/> 98 </xsl:call-template> 99 </xsl:for-each> 100 </xsl:element> 101 </xsl:when> 102 <!-- Other elements are only added if found. --> 103 <xsl:otherwise> 104 <axsl:apply-templates select="{$path}"/> 105 </xsl:otherwise> 106 </xsl:choose> 107 </xsl:template> 108 109 110 111 <!-- Process rules. --> 112 113 <xsl:template name="process-rules"> 114 115 <!-- Define elements which do not have selectors. --> 116 <!-- NOTE: Duplicating adding-selectors - see above. --> 117 <xsl:variable name="adding-selectors" select="count(//selector[@element=current()/@name])"/> 118 119 <xsl:choose> 120 <xsl:when test="@type='multiple-choice-value' or @type='multiple-choice-list-value'"> 121 <!-- Do not match multiple-choice values. --> 122 </xsl:when> 123 <xsl:when test="$adding-selectors = 0"> 124 <xsl:for-each select="element"> 125 <xsl:call-template name="process-rules"/> 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 <axsl:for-each select="${../@name}/{../@name}/{@name}"> 140 <axsl:copy> 141 <axsl:apply-templates select="@*"/> 142 <xsl:if test="@type='multiple-choice-list-value'"> 143 <axsl:if test="$values[string() = current()/@{attribute/@name}]"> 144 <axsl:attribute name="{@expr-name}">1</axsl:attribute> 145 </axsl:if> 146 </xsl:if> 147 </axsl:copy> 148 </axsl:for-each> 149 </xsl:template> 150 151 </xsl:stylesheet>