tags:

views:

11

answers:

1

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!

+2  A: 

This stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
    <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"&gt;
    <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"&gt;
    <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>
Alejandro
Thank you Alejandro! One more thing: if I have teams/teamOne/members/allow and teams/teamTwo/members/deny and this replied for teamTwo teams/teamOne/members/allow and teams/teamOne/members/deny... how can I apply only a template to process the same information? Wish my question is clear. Thank you!
Isern Palaus
@Isern Palaus: You are wellcome! About second question: it looks like you want to process only some elements and bypass others. Please, ask new question with input sample for better response.
Alejandro