Therefore, XSLT is not suitable for string processing. With XSLT 2.0, things get better as more string functions are available and sequence-based operations are possible.
In XSLT 1.0 (which is still the most portable version for writing code), character-by-character processing can only be achieved by recursion. For pleasure it is:
<xsl:output method="text" /> <xsl:variable name="CRLF" select="' '" /> <xsl:template match="/mytag"> <xsl:call-template name="reverse-string"> <xsl:with-param name="s" select="string(.)" /> </xsl:call-template> <xsl:value-of select="$CRLF" /> <xsl:call-template name="vertical-string"> <xsl:with-param name="s" select="string(.)" /> </xsl:call-template> </xsl:template> <xsl:template name="reverse-string"> <xsl:param name="s" select="''" /> <xsl:variable name="l" select="string-length($s)" /> <xsl:value-of select="substring($s, $l, 1)" /> <xsl:if test="$l > 0"> <xsl:call-template name="reverse-string"> <xsl:with-param name="s" select="substring($s, 1, $l - 1)" /> </xsl:call-template> </xsl:if> </xsl:template> <xsl:template name="vertical-string"> <xsl:param name="s" select="''" /> <xsl:variable name="l" select="string-length($s)" /> <xsl:value-of select="concat(substring($s, 1, 1), $CRLF)" /> <xsl:if test="$l > 0"> <xsl:call-template name="vertical-string"> <xsl:with-param name="s" select="substring($s, 2, $l)" /> </xsl:call-template> </xsl:if> </xsl:template>
It produces:
ataD modnaR R a n d o m D a t a
EDIT: To be clear: I do not support the actual use of the above code. Presentation issues must be addressed at the presentation level. The above will work, but char -by-char recursion is one of the most inefficient ways to do string processing, and if you have no other choice, avoid string handling in XSLT.
source share