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 <xsl:variable name="template-expr">http://www.boddie.org.uk/ns/xmltools/template-expr</xsl:variable> 10 11 <!-- Match the document itself. --> 12 13 <xsl:template match="/"> 14 <axsl:stylesheet version="1.0"> 15 <axsl:template match="/"> 16 17 <!-- Include the remaining attributes. --> 18 <xsl:apply-templates select="@*"/> 19 20 <!-- Process the elements. --> 21 <xsl:apply-templates select="*"/> 22 23 </axsl:template> 24 </axsl:stylesheet> 25 </xsl:template> 26 27 28 29 <!-- Match element references. --> 30 31 <xsl:template match="*[@template:element]"> 32 <xsl:call-template name="enter-element"> 33 <xsl:with-param name="other-elements" select="@template:element"/> 34 </xsl:call-template> 35 </xsl:template> 36 37 <xsl:template name="enter-element"> 38 <xsl:param name="other-elements"/> 39 <xsl:variable name="first-element" select="substring-before($other-elements, ',')"/> 40 <xsl:variable name="remaining-elements" select="substring-after($other-elements, ',')"/> 41 <xsl:choose> 42 <xsl:when test="$first-element = ''"> 43 <xsl:call-template name="next-element"> 44 <xsl:with-param name="first-element" select="$other-elements"/> 45 </xsl:call-template> 46 </xsl:when> 47 <xsl:otherwise> 48 <xsl:call-template name="next-element"> 49 <xsl:with-param name="first-element" select="$first-element"/> 50 <xsl:with-param name="remaining-elements" select="$remaining-elements"/> 51 </xsl:call-template> 52 </xsl:otherwise> 53 </xsl:choose> 54 </xsl:template> 55 56 <xsl:template name="next-element"> 57 <xsl:param name="first-element"/> 58 <xsl:param name="remaining-elements"/> 59 <axsl:for-each select="{$first-element}"> 60 <xsl:choose> 61 <xsl:when test="$remaining-elements = ''"> 62 <xsl:call-template name="special-attributes"/> 63 </xsl:when> 64 <xsl:otherwise> 65 <xsl:call-template name="enter-element"> 66 <xsl:with-param name="other-elements" select="$remaining-elements"/> 67 </xsl:call-template> 68 </xsl:otherwise> 69 </xsl:choose> 70 </axsl:for-each> 71 </xsl:template> 72 73 74 75 <!-- Match special expression attributes. --> 76 77 <xsl:template match="*[not(@template:element) and (@template:attribute or @template:value or @template:expr)]"> 78 <xsl:call-template name="special-attributes"/> 79 </xsl:template> 80 81 <xsl:template name="special-attributes"> 82 <xsl:choose> 83 <xsl:when test="@template:effect = 'replace'"> 84 <xsl:call-template name="special-values"/> 85 </xsl:when> 86 <xsl:otherwise> 87 <xsl:copy> 88 <xsl:apply-templates select="@*"/> 89 <xsl:if test="@template:expr and @template:expr-attr"> 90 <axsl:if test="{@template:expr}"> 91 <axsl:attribute name="{@template:expr-attr}"><xsl:value-of select="@template:expr-attr"/></axsl:attribute> 92 </axsl:if> 93 </xsl:if> 94 <xsl:call-template name="special-values"/> 95 </xsl:copy> 96 </xsl:otherwise> 97 </xsl:choose> 98 </xsl:template> 99 100 <xsl:template name="special-values"> 101 <xsl:choose> 102 <xsl:when test="@template:attribute"> 103 <axsl:choose> 104 <axsl:when test="@{@template:attribute}"> 105 <axsl:variable name="this-name"><xsl:value-of select="@template:attribute"/></axsl:variable> 106 <axsl:variable name="this-value" select="@{@template:attribute}"/> 107 <xsl:call-template name="special-value"/> 108 </axsl:when> 109 <axsl:otherwise> 110 <axsl:variable name="this-name"><xsl:value-of select="@template:attribute"/></axsl:variable> 111 <axsl:variable name="this-value"></axsl:variable> 112 <xsl:call-template name="special-value"/> 113 </axsl:otherwise> 114 </axsl:choose> 115 </xsl:when> 116 <xsl:otherwise> 117 <xsl:call-template name="special-value"/> 118 </xsl:otherwise> 119 </xsl:choose> 120 </xsl:template> 121 122 <xsl:template name="special-value"> 123 <xsl:choose> 124 <xsl:when test="@template:value"> 125 <axsl:value-of select="{@template:value}"/> 126 </xsl:when> 127 <xsl:otherwise> 128 <xsl:apply-templates select="node()"/> 129 </xsl:otherwise> 130 </xsl:choose> 131 </xsl:template> 132 133 134 135 <!-- Remove template elements. --> 136 137 <xsl:template match="@template:element|@template:attribute|@template:value|@template:expr|@template:expr-attr|@template:effect"> 138 </xsl:template> 139 140 141 142 <!-- Replicate unknown elements. --> 143 144 <xsl:template match="@*|node()"> 145 <xsl:copy> 146 <xsl:apply-templates select="@*|node()"/> 147 </xsl:copy> 148 </xsl:template> 149 150 </xsl:stylesheet>