[xsl] Recursive string replace in XSLT 2.0

Subject: [xsl] Recursive string replace in XSLT 2.0
From: "Rick Quatro rick@xxxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 6 Jan 2017 19:10:10 -0000
Hi. I am trying to make a recursive template so I can do a series of
find/changes on text nodes. I may have a lot of them, so I wanted to avoid
nested replace function calls. I am using a parameter for my find/change
pairs. In the recursive call, I am trying to use the current parameter with
[position()>1] to "pop" the first one off the list. It is not working and I
think it is a problem with this line: 

<xsl:with-param name="regex" select="$regex/regex[position()>1]"/>

but I am not sure the correct way to do this.

Here is my input file:

<?xml version='1.0' encoding='UTF-8'?>
<test><p class="Note">abcdefghij.</p></test>

Here is my stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
    xmlns:xs="http://www.w3.org/2001/XMLSchema";
    exclude-result-prefixes="xs"
    version="2.0">
    
    <xsl:output indent="yes"/>
    
    <xsl:param name="regexes">
        <regex><find>a</find><change>x</change></regex>
        <regex><find>b</find><change>y</change></regex>
        <regex><find>c</find><change>z</change></regex>
    </xsl:param>
    
    <xsl:template match="/">
        <xsl:apply-templates/>
    </xsl:template>
    
    <xsl:template match="p">
        <p><xsl:apply-templates/></p>
    </xsl:template>
    
    <xsl:template match="text()[string-length(.)>0]">
        <xsl:message select="."></xsl:message>
        <xsl:call-template name="applyRegexes">
            <xsl:with-param name="nodeText" select="."/>
            <xsl:with-param name="regex" select="$regexes"/>
         </xsl:call-template>
    </xsl:template>
    
    <xsl:template name="applyRegexes">
        <xsl:param name="nodeText"/>
        <xsl:param name="regex"/>
        <xsl:message select="$regex"></xsl:message>
        <xsl:message select="$regex/regex[1]"/>
        <xsl:message select="$regex/regex[position()>1]"/>
        <xsl:choose>
            <xsl:when test="count($regex/regex)">
                <xsl:variable name="temp">
                    <xsl:value-of
select="replace($nodeText,$regex/regex[1]/find,$regex/regex[1]/change)"/>
                </xsl:variable>
                <xsl:call-template name="applyRegexes">
                    <xsl:with-param name="nodeText" select="$temp"/>
                    <xsl:with-param name="regex"
select="$regex/regex[position()>1]"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$nodeText"/>
            </xsl:otherwise>
        </xsl:choose>
     </xsl:template>
    
</xsl:stylesheet>

Thanks in advance for any help or pointers.

Rick Quatro
Carmen Publishing Inc.
rick@xxxxxxxxxxxxxxx
585-366-4017

Current Thread