str.tokenize.keep.delimiters

str.tokenize.keep.delimiters — Tokenize a string while preserving any delimiters

Description

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.

Note

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>