1<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 2 3<xsl:template match="towerheight"> 4 5 6 <xsl:output encoding="utf-8"/> 7 8 9 <xsl:variable name="height"> 10 <xsl:value-of select="."/> 11 </xsl:variable> 12 13 <xsl:variable name="tower"> 14 <xsl:call-template name="initialize"> 15 <xsl:with-param name="height" select="$height"/> 16 </xsl:call-template> 17 </xsl:variable> 18 19 <towers> 20 <xsl:copy-of select="$tower"/> 21 <xsl:call-template name="transferstack"> 22 <xsl:with-param name="tower" select="$tower"/> 23 <xsl:with-param name="source" select="'left'"/> 24 <xsl:with-param name="target" select="'center'"/> 25 <xsl:with-param name="spare" select="'right'"/> 26 <xsl:with-param name="howmany" select="$height"/> 27 </xsl:call-template> 28 </towers> 29 30</xsl:template> 31 32<xsl:template name="initialize"> 33 <xsl:param name="height"/> 34 <tower> 35 <leftstack> 36 <xsl:call-template name="initstack"> 37 <xsl:with-param name="height" select="$height"/> 38 </xsl:call-template> 39 </leftstack> 40 <centerstack/> 41 <rightstack/> 42 </tower> 43</xsl:template> 44 45<xsl:template name="initstack"> 46 <xsl:param name="height"/> 47 <xsl:param name="size" select="0"/> 48 <xsl:if test="$size > 0"> 49 <disc size="{$size}"/> 50 </xsl:if> 51 <xsl:if test="$size < $height"> 52 <xsl:call-template name="initstack"> 53 <xsl:with-param name="height" select="$height"/> 54 <xsl:with-param name="size" select="$size + 1"/> 55 </xsl:call-template> 56 </xsl:if> 57</xsl:template> 58 59<xsl:template name="transferstack"> 60 <xsl:param name="tower"/> 61 <xsl:param name="source"/> 62 <xsl:param name="target"/> 63 <xsl:param name="spare"/> 64 <xsl:param name="howmany"/> 65 66 <xsl:if test="$howmany > 0"> 67 68 <xsl:variable name="firstpart"> 69 <xsl:call-template name="transferstack"> 70 <xsl:with-param name="tower" select="$tower"/> 71 <xsl:with-param name="source" select="$source"/> 72 <xsl:with-param name="target" select="$spare"/> 73 <xsl:with-param name="spare" select="$target"/> 74 <xsl:with-param name="howmany" select="$howmany - 1"/> 75 </xsl:call-template> 76 </xsl:variable> 77 78 <xsl:variable name="lasttower"> 79 <xsl:choose> 80 <xsl:when test="$firstpart/tower[last()]"> 81 <xsl:copy-of select="$firstpart/tower[last()]"/> 82 </xsl:when> 83 <xsl:otherwise> 84 <xsl:copy-of select="$tower"/> 85 </xsl:otherwise> 86 </xsl:choose> 87 </xsl:variable> 88 89 <xsl:variable name="secondpart"> 90 <xsl:call-template name="transferdisc"> 91 <xsl:with-param name="tower" select="$lasttower"/> 92 <xsl:with-param name="source" select="$source"/> 93 <xsl:with-param name="target" select="$target"/> 94 </xsl:call-template> 95 </xsl:variable> 96 97 <xsl:copy-of select="$firstpart"/> 98 <xsl:copy-of select="$secondpart"/> 99 100 <xsl:call-template name="transferstack"> 101 <xsl:with-param name="tower" select="$secondpart"/> 102 <xsl:with-param name="source" select="$spare"/> 103 <xsl:with-param name="target" select="$target"/> 104 <xsl:with-param name="spare" select="$source"/> 105 <xsl:with-param name="howmany" select="$howmany - 1"/> 106 </xsl:call-template> 107 108 </xsl:if> 109</xsl:template> 110 111<xsl:template name="transferdisc"> 112 <xsl:param name="tower"/> 113 <xsl:param name="source"/> 114 <xsl:param name="target"/> 115 116 <xsl:variable name="disc"> 117 <xsl:choose> 118 <xsl:when test="$source = 'left'"> 119 <xsl:copy-of select="$tower/tower/leftstack/disc[1]"/> 120 </xsl:when> 121 <xsl:when test="$source = 'center'"> 122 <xsl:copy-of select="$tower/tower/centerstack/disc[1]"/> 123 </xsl:when> 124 <xsl:otherwise> 125 <xsl:copy-of select="$tower/tower/rightstack/disc[1]"/> 126 </xsl:otherwise> 127 </xsl:choose> 128 </xsl:variable> 129 130 <xsl:variable name="newleft"> 131 <xsl:choose> 132 <xsl:when test="$source = 'left'"> 133 <leftstack> 134 <xsl:copy-of select="$tower/tower/leftstack/disc[position() > 1]"/> 135 </leftstack> 136 </xsl:when> 137 <xsl:when test="$target = 'left'"> 138 <leftstack> 139 <xsl:copy-of select="$disc"/> 140 <xsl:copy-of select="$tower/tower/leftstack/disc"/> 141 </leftstack> 142 </xsl:when> 143 <xsl:otherwise> 144 <xsl:copy-of select="$tower/tower/leftstack"/> 145 </xsl:otherwise> 146 </xsl:choose> 147 </xsl:variable> 148 149 <xsl:variable name="newcenter"> 150 <xsl:choose> 151 <xsl:when test="$source = 'center'"> 152 <centerstack> 153 <xsl:copy-of select="$tower/tower/centerstack/disc[position() > 1]"/> 154 </centerstack> 155 </xsl:when> 156 <xsl:when test="$target = 'center'"> 157 <centerstack> 158 <xsl:copy-of select="$disc"/> 159 <xsl:copy-of select="$tower/tower/centerstack/disc"/> 160 </centerstack> 161 </xsl:when> 162 <xsl:otherwise> 163 <xsl:copy-of select="$tower/tower/centerstack"/> 164 </xsl:otherwise> 165 </xsl:choose> 166 </xsl:variable> 167 168 <xsl:variable name="newright"> 169 <xsl:choose> 170 <xsl:when test="$source = 'right'"> 171 <rightstack> 172 <xsl:copy-of select="$tower/tower/rightstack/disc[position() > 1]"/> 173 </rightstack> 174 </xsl:when> 175 <xsl:when test="$target = 'right'"> 176 <rightstack> 177 <xsl:copy-of select="$disc"/> 178 <xsl:copy-of select="$tower/tower/rightstack/disc"/> 179 </rightstack> 180 </xsl:when> 181 <xsl:otherwise> 182 <xsl:copy-of select="$tower/tower/rightstack"/> 183 </xsl:otherwise> 184 </xsl:choose> 185 </xsl:variable> 186 187 <tower> 188 <xsl:copy-of select="$newleft"/> 189 <xsl:copy-of select="$newcenter"/> 190 <xsl:copy-of select="$newright"/> 191 </tower> 192</xsl:template> 193 194</xsl:stylesheet> 195