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 <axsl:template select="/"> 20 21 <!-- Process the elements. --> 22 <xsl:apply-templates select="*"/> 23 24 </axsl:template> 25 26 </axsl:stylesheet> 27 </xsl:template> 28 29 30 31 <!-- Match element references. --> 32 33 <xsl:template match="*[@template:element]"> 34 <xsl:call-template name="enter-element"> 35 <xsl:with-param name="other-elements" select="@template:element"/> 36 </xsl:call-template> 37 </xsl:template> 38 39 <xsl:template name="enter-element"> 40 <xsl:param name="other-elements"/> 41 <xsl:variable name="first-element" select="substring-before($other-elements, ',')"/> 42 <xsl:variable name="remaining-elements" select="substring-after($other-elements, ',')"/> 43 <xsl:choose> 44 <xsl:when test="$first-element = ''"> 45 <xsl:call-template name="next-element"> 46 <xsl:with-param name="first-element" select="$other-elements"/> 47 </xsl:call-template> 48 </xsl:when> 49 <xsl:otherwise> 50 <xsl:call-template name="next-element"> 51 <xsl:with-param name="first-element" select="$first-element"/> 52 <xsl:with-param name="remaining-elements" select="$remaining-elements"/> 53 </xsl:call-template> 54 </xsl:otherwise> 55 </xsl:choose> 56 </xsl:template> 57 58 <xsl:template name="next-element"> 59 <xsl:param name="first-element"/> 60 <xsl:param name="remaining-elements"/> 61 <axsl:for-each select="{$first-element}"> 62 <axsl:element name="{$first-element}"> 63 <xsl:choose> 64 <xsl:when test="$remaining-elements = ''"> 65 <xsl:call-template name="enter-attribute"/> 66 </xsl:when> 67 <xsl:otherwise> 68 <xsl:call-template name="enter-element"> 69 <xsl:with-param name="other-elements" select="$remaining-elements"/> 70 </xsl:call-template> 71 </xsl:otherwise> 72 </xsl:choose> 73 </axsl:element> 74 </axsl:for-each> 75 </xsl:template> 76 77 78 79 <!-- Match special expression attributes. --> 80 81 <xsl:template match="*[not(@template:element) and @template:attribute]"> 82 <xsl:call-template name="enter-attribute"/> 83 </xsl:template> 84 85 <xsl:template name="enter-attribute"> 86 <xsl:choose> 87 <xsl:when test="@template:attribute"> 88 <axsl:choose> 89 <axsl:when test="@{@template:attribute}"> 90 <axsl:attribute name="{@template:attribute}"><axsl:value-of select="@{@template:attribute}"/></axsl:attribute> 91 <xsl:apply-templates select="*"/> 92 </axsl:when> 93 <axsl:otherwise> 94 <axsl:attribute name="{@template:attribute}"/> 95 <xsl:apply-templates select="*"/> 96 </axsl:otherwise> 97 </axsl:choose> 98 </xsl:when> 99 <xsl:otherwise> 100 <xsl:apply-templates select="*"/> 101 </xsl:otherwise> 102 </xsl:choose> 103 </xsl:template> 104 105 106 107 <!-- Traverse unknown elements. --> 108 109 <xsl:template match="*"> 110 <xsl:apply-templates select="*"/> 111 </xsl:template> 112 113 </xsl:stylesheet>