str.tokenize.keep.delimiters — Tokenize a string while preserving any delimiters
Based on the occurrence of one or more delimiter characters,
this function breaks a string into a list of tokens and delimiters,
marking up each of the tokens with a token element
and preserving the delimiters as text nodes between the tokens.
This function is a very slightly modified version of a function from the EXSLT site. The original is available at:
The str.tokenize.keep.delimiters function
differs only in that it preserves the delimiters instead of
discarding them.
<xsl:template name="str.tokenize.keep.delimiters">
<xsl:param name="string" select="''"></xsl:param>
<xsl:param name="delimiters" select="' '"></xsl:param>
<xsl:choose>
<xsl:when test="not($string)"></xsl:when>
<xsl:when test="not($delimiters)">
<xsl:call-template name="str.tokenize.keep.delimiters-characters">
<xsl:with-param name="string" select="$string"></xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="str.tokenize.keep.delimiters-delimiters">
<xsl:with-param name="string" select="$string"></xsl:with-param>
<xsl:with-param name="delimiters" select="$delimiters"></xsl:with-param>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="str.tokenize.keep.delimiters-characters">
<xsl:param name="string"></xsl:param>
<xsl:if test="$string">
<ssb:token><xsl:value-of select="substring($string, 1, 1)"></xsl:value-of></ssb:token>
<xsl:call-template name="str.tokenize.keep.delimiters-characters">
<xsl:with-param name="string" select="substring($string, 2)"></xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="str.tokenize.keep.delimiters-delimiters">
<xsl:param name="string"></xsl:param>
<xsl:param name="delimiters"></xsl:param>
<xsl:variable name="delimiter" select="substring($delimiters, 1, 1)"></xsl:variable>
<xsl:choose>
<xsl:when test="not($delimiter)">
<ssb:token><xsl:value-of select="$string"></xsl:value-of></ssb:token>
</xsl:when>
<xsl:when test="contains($string, $delimiter)">
<xsl:if test="not(starts-with($string, $delimiter))">
<xsl:call-template name="str.tokenize.keep.delimiters-delimiters">
<xsl:with-param name="string" select="substring-before($string, $delimiter)"></xsl:with-param>
<xsl:with-param name="delimiters" select="substring($delimiters, 2)"></xsl:with-param>
</xsl:call-template>
</xsl:if>
<!-- output each delimiter -->
<xsl:value-of select="$delimiter"></xsl:value-of>
<xsl:call-template name="str.tokenize.keep.delimiters-delimiters">
<xsl:with-param name="string" select="substring-after($string, $delimiter)"></xsl:with-param>
<xsl:with-param name="delimiters" select="$delimiters"></xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="str.tokenize.keep.delimiters-delimiters">
<xsl:with-param name="string" select="$string"></xsl:with-param>
<xsl:with-param name="delimiters" select="substring($delimiters, 2)"></xsl:with-param>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>