Mike Kay
> Could a call-template be written that took two parameters (a
> string, and a
> number) return the string with empty spaces appended to the
> end so that it
> occupied the number of spaces specified by the number
> parameter?
So long as you know the number of spaces will never exceed say 100, write
<xsl:template name="pad">
<xsl:param name="s"/>
<xsl:param name="len"/>
<xsl:variable name="spaces"> ... </xsl:variable>
<xsl:value-of select="substring(concat($s, $spaces), 1, $len)"/>
</xsl:template>
A more elegant solution, which handles any number of spaces, is for the
template to append one space to the string and then call itself to add
another "len-1", until len reaches zero.
Wendell Piez adds
You should check out XPath's
string-handling functions.
Something like
<xsl:value-of
select="substring(concat($string, ' '), 1, 12))"/> Always gives you a string twelve characters long, either the first twelve
characters of $string, or $string padded out with spaces. Variables can be
also be useful to make things easier to read, reuse and maintain -- for
example
<xsl:variable name="spacex12" select="' '"/>
and then
<xsl:value-of select="substring(concat($string, $spacex12), 1, 12))"/>
Bob DuCharme provides the example:
Just as a challenge, I took it a little further. The following outputs the
color values in this document
<test>
<color>red</color>
<color>blue</color>
<color>yellow</color>
</test>
at 12 characters each, right aligned:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:variable name="fieldWidth">12</xsl:variable>
<xsl:template match="color">
<xsl:variable name="valueLength"
select="string-length(normalize-space(.))"/>
<xsl:variable name="padding"
select="$fieldWidth - $valueLength"/>
<xsl:text>[</xsl:text>
<xsl:value-of select="substring(' ',1,$padding)"/>
<xsl:value-of select="."/>
<xsl:text>]</xsl:text>
</xsl:template>
</xsl:stylesheet>
giving this output:
<?xml version="1.0" encoding="utf-8"?>
[ red]
[ blue]
[ yellow]
Nate Austin adds, for Fixed-length String Output
Here are the string padding functions that I use frequently:
<xsl:template name="prepend-pad">
<!-- recursive template to right justify and prepend-->
<!-- the value with whatever padChar is passed in -->
<xsl:param name="padChar"> </xsl:param>
<xsl:param name="padVar"/>
<xsl:param name="length"/>
<xsl:choose>
<xsl:when test="string-length($padVar) < $length">
<xsl:call-template name="prepend-pad">
<xsl:with-param name="padChar" select="$padChar"/>
<xsl:with-param name="padVar" select="concat($padChar,$padVar)"/>
<xsl:with-param name="length" select="$length"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring($padVar,string-length($padVar) -
$length + 1)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="append-pad">
<!-- recursive template to left justify and append -->
<!-- the value with whatever padChar is passed in -->
<xsl:param name="padChar"> </xsl:param>
<xsl:param name="padVar"/>
<xsl:param name="length"/>
<xsl:choose>
<xsl:when test="string-length($padVar) < $length">
<xsl:call-template name="append-pad">
<xsl:with-param name="padChar" select="$padChar"/>
<xsl:with-param name="padVar" select="concat($padVar,$padChar)"/>
<xsl:with-param name="length" select="$length"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring($padVar,1,$length)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
These will both ensure that the string ends up to be whatever length you
pass in (ie. if the string is longer than expected it will also truncate).
Pete Forman adds an option for left padding Here's an example of padding on the left using a similar
technique. It prints my size attribute to a width of 4.
<xsl:value-of select="substring(concat(' ', @size),
string-length(@size) + 1, 4)"/>
This is clearly not as versatile as some of the
solutions but it suffices for simple cases. |