ipalaus
ipalaus

Reputation: 2273

Transform with XSLT a XML list into a comma-separated with 'and' for the last entries and a final

I have a list like:

<members>
    <name>Lorem Ipsum</name>
    <name>Lorem Ipsum</name>
    <name>Lorem Ipsum</name>
    <name>Lorem Ipsum</name>
</members>

That I need to conver to:

Lorem Ipsum, Lorem Ipsum, Lorem Ipsum and Lorem Ipsum.

How this can be done? I suppose that in XSLT 1.0 I will need to loop for-each, but how to apply a comma, and or . depending of his position?

Thank you in advance!

Upvotes: 0

Views: 147

Answers (1)

user357812
user357812

Reputation:

This stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="name">
        <xsl:variable name="vFollowing" 
                      select="count(following-sibling::name)"/>
        <xsl:value-of 
             select="concat(.,substring(', ',1 div ($vFollowing > 1)),
                              substring(' and ',1 div ($vFollowing = 1)),
                              substring('.',1 div ($vFollowing = 0)))"/>
    </xsl:template>
</xsl:stylesheet>

Output:

Lorem Ipsum, Lorem Ipsum, Lorem Ipsum and Lorem Ipsum.

EDIT: Also with fn:position() and fn:last()

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="name">
        <xsl:value-of 
             select="concat(.,substring(', ',1 div (last()-1 > position())),
                              substring(' and ',1 div (last()-1 = position())),
                              substring('.',1 div (last()=position())))"/>
    </xsl:template>
</xsl:stylesheet>

EDIT 2: The pattern matching solution.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="name">
        <xsl:value-of select="concat(.,', ')"/>
    </xsl:template>
    <xsl:template match="name[last()-1 = position()]">
        <xsl:value-of select="concat(.,' and ')"/>
    </xsl:template>
    <xsl:template match="name[last()]">
        <xsl:value-of select="concat(.,'.')"/>
    </xsl:template>
</xsl:stylesheet>

Upvotes: 2

Related Questions