Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement XSLT tokenize function?

It seems like EXSLT tokenize function is not available with PHP XSLTProcessor (XSLT 1.0).

I tried to implement it in pure XSL but I can't make it work :

<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:func="http://exslt.org/functions"
    xmlns:exsl="http://exslt.org/common"
    xmlns:my="http://mydomain.com/">

    <func:function name="my:tokenize">
        <xsl:param name="string"/>
        <xsl:param name="separator" select="'|'"/>
        <xsl:variable name="item" select="substring-before(concat($string,$separator),$separator)"/>
        <xsl:variable name="remainder" select="substring-after($string,$separator)"/>
        <xsl:variable name="tokens">
            <token><xsl:value-of select="$item"/></token>
            <xsl:if test="$remainder!=''">
                <xsl:copy-of select="my:tokenize($remainder,$separator)"/>
            </xsl:if>
        </xsl:variable>
        <func:result select="exsl:node-set($tokens)"/>
    </func:function>

    <xsl:template match="/">
        <xsl:copy-of select="my:tokenize('a|b|c')"/>
    </xsl:template>

</xsl:stylesheet>

Expected result :

    <token>a</token><token>b</token><token>c</token>

Actual result :

    abc

I know this question has been posted many times but I can't find a simple solution.

Thank you for your help.

like image 450
Mathieu Bautista Avatar asked Jan 16 '23 18:01

Mathieu Bautista


1 Answers

Quoting http://www.exslt.org/str/functions/tokenize/index.html

The following XSLT processors support str:tokenize:

  • 4XSLT, from 4Suite. (version 0.12.0a3)
  • libxslt from Daniel Veillard et al. (version 1.0.19)

Since PHP uses libxslt, it means tokenize is available, but you have to use the right extension namespaces (which you dont do):

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:str="http://exslt.org/strings"
    extension-element-prefixes="str"
    …

Then you can use tokenize as a function, for example to build a select box with numbers 1-12:

<select name="months">
    <xsl:for-each select="str:tokenize('1,2,3,4,5,6,7,8,9,10,11,12', ',')">
        <xsl:element name="option">
            <xsl:attribute name="value">
                <xsl:value-of select="."/>
            </xsl:attribute>
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:for-each>
</select>
like image 164
Gordon Avatar answered Jan 25 '23 15:01

Gordon