Converting an integer value to a repeating character
When my XSL stylesheets come across this node:
<node attribute="3"/> ... he should convert it to this node:
<node attribute="***"/> My template matches the attribute and recreates it, but I do not know how to set the value: the '*' symbol is repeated as many times as the value of the original attribute.
<xsl:template match="node/@attribute"> <xsl:variable name="repeat" select="."/> <xsl:attribute name="attribute"> <!-- What goes here? I think I can do something with $repeat... --> </xsl:attribute> </xsl:template> Thanks!
A rather dirty but pragmatic approach would be to make a call about what the largest number you expect to see in attribute , then use
substring("****...", 1, $repeat) where you have as many * in this line as the maximum number you expect. But I hope there is something better!
General, recursive solution (XSLT 1.0):
<xsl:template name="RepeatString"> <xsl:param name="string" select="''" /> <xsl:param name="times" select="1" /> <xsl:if test="number($times) > 0"> <xsl:value-of select="$string" /> <xsl:call-template name="RepeatString"> <xsl:with-param name="string" select="$string" /> <xsl:with-param name="times" select="$times - 1" /> </xsl:call-template> </xsl:if> </xsl:template> Call as:
<xsl:attribute name="attribute"> <xsl:call-template name="RepeatString"> <xsl:with-param name="string" select="'*'" /> <xsl:with-param name="times" select="." /> </xsl:call-template> </xsl:attribute> Adding @AakashM and @Tomalak to the two nice answers , this is done naturally in XSLT 2.0 :
Convert XSLT 2.0 :
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="@attribute"> <xsl:attribute name="{name()}"> <xsl:for-each select="1 to ."> <xsl:value-of select="'*'"/> </xsl:for-each> </xsl:attribute> </xsl:template> </xsl:stylesheet> when applied to the provided XML document :
<node attribute="3"/> creates the desired result :
<node attribute="***"/> Note how the XPath 2.0 to statement is used in the <xsl:for-each> statement.