Thomas
Thomas

Reputation: 21

simple loop in xslt

Having trouble figuring out a simple XSLT loop that counts and returns the name of the actor.

<stars>
  <star ID="001">Leonardo DiCaprio</star>
  <star ID="002">Matt Damon</star>
  <star ID="003">Jack Nicholson</star>
</stars>

This is what I made to give the result I wanted but if there was a fourth or fifth actor I would need to add to the code.

<xsl:value-of select="stars/star[@ID='001']"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="stars/star[@ID='002']"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="stars/star[@ID='003']"/>

Basically I need the loop to display the name of the star separated by a comma. Any help is appreciated.

Upvotes: 2

Views: 309

Answers (3)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243449

This is probably one of the simplest transformations -- note that there is neither need for xsl:for-each nor for any explicit XSLT conditional instruction:

<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="star[position() >1]">
  <xsl:text>, </xsl:text><xsl:apply-templates/>
 </xsl:template>
</xsl:stylesheet>

when applied on the provided source XML document:

<stars>
    <star ID="001">Leonardo DiCaprio</star>
    <star ID="002">Matt Damon</star>
    <star ID="003">Jack Nicholson</star>
</stars>

the wanted, correct output is produced:

Leonardo DiCaprio, Matt Damon, Jack Nicholson

Upvotes: 1

Oded
Oded

Reputation: 499002

Use a template instead of looping. XSLT processors are optimized for template matching.

<xsl:template match="star">
  <xsl:value-of select="." />
  <xsl:if test="position() != last()">
    <xsl:text>, </xsl:text>
  </xsl:if>
</xsl:template>

Upvotes: 2

Emiliano Poggi
Emiliano Poggi

Reputation: 24826

You can use repetition instruction (without any worry about performance):

<xsl:template match="stars">
    <xsl:value-of select="star[1]"/>
    <xsl:for-each select="star[position()>1]">
        <xsl:value-of select="concat(', ',.)"/>
    </xsl:for-each>
</xsl:template>

gets:

Leonardo DiCaprio, Matt Damon, Jack Nicholson 

Upvotes: 1

Related Questions