building an XSLT string (variable) in a foreach loop
I don't believe you can use XSL variables to concatenate, because once a variable value is set, it can't be changed. Instead, I think you want something like:
<xsl:for-each select="catalog/cd"> <xsl:choose> <xsl:when test="position() = 1"> <xsl:value-of select="country"/> </xsl:when> <xsl:otherwise> ;<xsl:value-of select="country"/> </xsl:otherwise> </xsl:choose></xsl:for-each>
Does that make sense to you?
Edit: Just realized I may have misread how you were intending to use the variable. The snippet I posted above can be wrapped in a variable element for later use, if that's what you meant:
<xsl:variable name="VariableName"> <xsl:for-each select="catalog/cd"> <xsl:choose> <xsl:when test="position() = 1"> <xsl:value-of select="country"/> </xsl:when> <xsl:otherwise> ;<xsl:value-of select="country"/> </xsl:otherwise> </xsl:choose> </xsl:for-each></xsl:variable>
If you can use XSLT 2.0 then either of the following would work:
Use the string-join()
function:
<xsl:variable name="companies" select="string-join(catalog/cd/company, ';')" />
Use @separator
with xsl:value-of
:
<xsl:variable name="companies" > <xsl:value-of select="catalog/cd/company" separator=";" /></xsl:variable>
Here is one simple, true XSLT solution:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:strip-space elements="*"/> <xsl:template match="company"> <xsl:value-of select="."/> <xsl:if test="following::company">;</xsl:if> </xsl:template> <xsl:template match="text()"/></xsl:stylesheet>
When this transformation is applied on the provided XML document:
<catalog> <cd> <country>UK</country> <company>CBS Records</company> </cd> <cd> <country>USA</country> <company>RCA</company> </cd> <cd> <country>UK</country> <company>Virgin records</company> </cd></catalog>
the wanted, correct result (all companies concatenated together and delimited by a ;
) is produced:
CBS Records;RCA;Virgin records