Tokenize a String in XSLT 1.0

With XSLT 2.0 a method is provided, which tokenizes a string by a specific delimiter (e.q. commas, spaces or other) quite easily.

<xsl:variable name="stringList" select="tokenize('XPath is fun', ' ')"/>

This subsequently can be used to iterate over the individual String elements:

<xsl:for-each select="$stringList">
	<xsl:value-of select="." />
</xsl:for-each>

The result of this easy method call is tokenized by spaces, so we get:

"XPath", "is", "fun"

Unfortunately, this function is not provided in XSLT 1.0, but there is the possibility of realizing this without any 3rd party libraries (e.q. EXSLT). The following example shows, how this can be done with XSLT 1.0.

First we look at the XML snippet, which contains as example the color attribute with a comma seperated String. This String should be tokenized via XSLT on the delimiter ‘,’ for further processing of the substring.

<?xml version="1.0" encoding="UTF-8" ?> 
<cars>
    <car color="yellow,red,black">
        <model>Audi A6 Avant</model>
        <year>2012</year>
        <manufacturer >Audi</manufacturer>
        <date>02/07/2012</date>
    </car>
</cars>

The corresponding XSL stylesheet is straight forward. The first template matches for the car element. Here is checked, if the color attribute for this element exists. If this is the case, the custom tokenizeString template is called.

The special of the tokenizeString template is, that it is recursive. With each iteration the substring in front of the first delimiter is determined and processed. Anything left of the String is stored into another variable. Finally the last substring of the recursion does not contain a delimiter, so the second otherwise path is executed.

<?xml version="1.0" encoding="UTF-8"?>  
<xsl:stylesheet version="1.0" 
		xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
 
    <xsl:template match="/cars/car">
		
        <xsl:choose>

            <xsl:when test="boolean(./@color)">
                <xsl:call-template name="tokenizeString">
                    <xsl:with-param name="list" select="./@color"/>
                    <xsl:with-param name="delimiter" select="','"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise/>
			
        </xsl:choose>


    </xsl:template>
	
    <!--############################################################-->
    <!--## Template to tokenize strings                           ##-->
    <!--############################################################-->
    <xsl:template name="tokenizeString">
		<!--passed template parameter -->
        <xsl:param name="list"/>
        <xsl:param name="delimiter"/>
        <xsl:choose>
            <xsl:when test="contains($list, $delimiter)">                
                <color>
                    <!-- get everything in front of the first delimiter -->
                    <xsl:value-of select="substring-before($list,$delimiter)"/>
                </color>
                <xsl:call-template name="tokenizeString">
                    <!-- store anything left in another variable -->
                    <xsl:with-param name="list" select="substring-after($list,$delimiter)"/>
                    <xsl:with-param name="delimiter" select="$delimiter"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:choose>
                    <xsl:when test="$list = ''">
                        <xsl:text/>
                    </xsl:when>
                    <xsl:otherwise>
                        <color>
                            <xsl:value-of select="$list"/>
                        </color>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>	
 
</xsl:stylesheet> 

To show, the extracted single values can be further customized, this values are included into a new color tag. The output after XSLT 1.0 transformation is the following:

<?xml version="1.0" encoding="UTF-8"?>
<color>yellow</color>
<color>red</color>
<color>black</color>

You see, with a little extra effort it is possible to tokenize Strings for special cases also in XSL 1.0. And the advantage -> It is XSL standard behavior without any 3rd party libraries!


This entry was posted in XML, XSL and tagged , , . Bookmark the permalink.

2 Responses to Tokenize a String in XSLT 1.0

  1. Dogan says:

    Hi, its very usefull article, thanks for all…

  2. Stepan says:

    Hey, thanks for your time, works like a charm!

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>