You can define a named template add_character_at_position
that inserts one character at a given position as follows:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="data">
<result>
<xsl:for-each select="string">
<string>
<xsl:call-template name="add_character_at_position">
<xsl:with-param name="string" select="."/>
<xsl:with-param name="position" select="@pos"/>
</xsl:call-template>
</string>
</xsl:for-each>
</result>
</xsl:template>
<xsl:template name="add_character_at_position_recurse">
<xsl:param name="prefix"/>
<xsl:param name="suffix"/>
<xsl:param name="position"/>
<xsl:param name="char"/>
<xsl:param name="seperator"/>
<xsl:choose>
<xsl:when test="$position = 0">
<xsl:value-of select="concat($prefix, $char, $suffix)"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="add_character_at_position_recurse">
<xsl:with-param name="prefix" select="concat($prefix, $seperator, substring-before(substring($suffix, 2), $seperator))"/>
<xsl:with-param name="suffix" select="concat($seperator, substring-after(substring($suffix,2), $seperator))"/>
<xsl:with-param name="position" select="$position - 1"/>
<xsl:with-param name="char" select="$char"/>
<xsl:with-param name="seperator" select="$seperator"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="add_character_at_position">
<xsl:param name="string"/>
<xsl:param name="position"/>
<xsl:param name="char" select="','"/>
<xsl:param name="seperator" select="' '"/>
<xsl:variable name="result">
<xsl:call-template name="add_character_at_position_recurse">
<xsl:with-param name="prefix" select="''"/>
<xsl:with-param name="suffix" select="concat($seperator, $string)"/>
<xsl:with-param name="position" select="$position"/>
<xsl:with-param name="char" select="$char"/>
<xsl:with-param name="seperator" select="$seperator"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="substring($result, 2)"/>
</xsl:template>
</xsl:stylesheet>
It uses recursion (as usual in XSLT 1.0) to split the string and insert the character between the current prefix
and suffix
. If you need several characters (commas) you will have to call this template nested several times. Note that the template currently does not any checking whether the position parameter is valid.
The test setup used the following input XML:
<?xml version="1.0" encoding="ISO-8859-1"?>
<data>
<string pos="5">My name is John Smith I have a bat its costs is $150</string>
</data>
Generating the following result:
<?xml version="1.0" encoding="UTF-8"?>
<result>
<string>My name is John Smith, I have a bat its costs is $150</string>
</result>