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 <xsl:param name="nested">false</xsl:param> 48 49 <!-- Make a rule for the element. --> 50 <axsl:template match="{@name}"> 51 52 <!-- Copy the element. --> 53 <xsl:element name="{@name}"> 54 55 <!-- Process attributes. --> 56 <axsl:apply-templates select="@*"/> 57 58 <!-- Find elements and determine how to process them. --> 59 <xsl:for-each select="element"> 60 <xsl:choose> 61 <!-- Enumerations. --> 62 <xsl:when test="@expr"> 63 <xsl:call-template name="inside-element"/> 64 </xsl:when> 65 <!-- Top-level or "section" elements are added. --> 66 <xsl:when test="count(attribute) = 0 or $nested = 'false'"> 67 <xsl:element name="{@name}"> 68 <xsl:call-template name="inside-element"/> 69 </xsl:element> 70 </xsl:when> 71 <!-- Other elements are only added if found. --> 72 <xsl:otherwise> 73 <axsl:apply-templates select="{@name}"/> 74 </xsl:otherwise> 75 </xsl:choose> 76 </xsl:for-each> 77 78 </xsl:element> 79 80 </axsl:template> 81 82 <!-- Make rules for nested elements. --> 83 <xsl:choose> 84 <xsl:when test="$nested = 'true'"> 85 <xsl:apply-templates select="*[not(@expr)]"> 86 <xsl:with-param name="nested">true</xsl:with-param> 87 </xsl:apply-templates> 88 </xsl:when> 89 <xsl:otherwise> 90 <xsl:apply-templates select="*/*[not(@expr)]"> 91 <xsl:with-param name="nested">true</xsl:with-param> 92 </xsl:apply-templates> 93 </xsl:otherwise> 94 </xsl:choose> 95 96 </xsl:template> 97 98 99 100 <!-- Fill in elements. --> 101 102 <xsl:template name="inside-element"> 103 <axsl:apply-templates select="{@name}/@*"/> 104 <xsl:choose> 105 <!-- Enumerations. --> 106 <xsl:when test="@expr"> 107 <xsl:call-template name="inside-enumeration"/> 108 </xsl:when> 109 <xsl:otherwise> 110 <!-- Enumeration containers. --> 111 <xsl:for-each select="*[@expr]"> 112 <xsl:call-template name="inside-element"/> 113 </xsl:for-each> 114 <!-- Normal elements. --> 115 <xsl:if test="count(element[not(@expr)]) != 0"> 116 <axsl:apply-templates select="{@name}/*"/> 117 </xsl:if> 118 </xsl:otherwise> 119 </xsl:choose> 120 </xsl:template> 121 122 123 124 <!-- Fill in enumerations. --> 125 126 <xsl:template name="inside-enumeration"> 127 <axsl:for-each select="${../@name}/{../@name}/{@name}"> 128 <axsl:copy> 129 <axsl:apply-templates select="@*"/> 130 </axsl:copy> 131 </axsl:for-each> 132 </xsl:template> 133 134 </xsl:stylesheet>