XSLT 1.0, Join a list of elements’s value with separator
By admin - Last updated: Thursday, February 26, 2009 - Save & Share - Leave a Comment
In order to join a sequence with a customized separator in XSLT 1.0, similar to C# function string.Join( array, separator), I’ve come up with a template which takes the sequence and separator as parameter.
Given a sample XML
<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" href="ElementJoin.xslt"?>
<Root>
<Years>
<int>2008</int>
<int>2009</int>
<int>2010</int>
</Years>
<Technologies>
<Java>SUN</Java>
<Csharp>MS</Csharp>
</Technologies>
</Root>
Expected output
Years: 2008,2009,2010
Technologies: SUN | MS
Technologies: SUN | MS
XSLT (1.0) referenced as ElementJoin.xslt
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl">
<xsl:output method="text" indent="yes"/>
<!-- join integer array by separator ',' -->
<xsl:template match="/Root/Years">
<xsl:value-of select="local-name()"/>
<xsl:text>: </xsl:text>
<xsl:call-template name="join">
<xsl:with-param name="valueList" select="*"/>
<xsl:with-param name="separator" select="','"/>
</xsl:call-template>
<xsl:text>

</xsl:text>
</xsl:template>
<!-- join children elements by separator ' | ' -->
<xsl:template match="/Root/Technologies">
<xsl:value-of select="local-name()"/>
<xsl:text>: </xsl:text>
<xsl:call-template name="join">
<xsl:with-param name="valueList" select="*"/>
<xsl:with-param name="separator" select="' | '"/>
</xsl:call-template>
<xsl:text>

</xsl:text>
</xsl:template>
<!-- template 'join' accepts valueList and separator -->
<xsl:template name="join" >
<xsl:param name="valueList" select="''"/>
<xsl:param name="separator" select="','"/>
<xsl:for-each select="$valueList">
<xsl:choose>
<xsl:when test="position() = 1">
<xsl:value-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($separator, .) "/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
This can be done easily with XPATH 2.0 fn:string-join(sequence, delimiter). However the current .NET only supports XSLT 1.0, XPATH 1.0. For advanced transformation, check out http://www.saxonica.com/documentation/changes/intro/xslt91.html