Andrew Truckle
Andrew Truckle

Reputation: 19197

Suppress trailing comma with xslt

I have this XSL:

  <xsl:for-each select="Name">
    <xsl:if test="@Highlight='true'">
      <td>
        <xsl:variable name="iColumnIndex" select="position()+1" />
        <xsl:value-of select="/SRRScheduleData/Columns/Heading[$iColumnIndex]"/>
        <xsl:text>, </xsl:text>
      </td>
    </xsl:if>
  </xsl:for-each>

The XML is question is simple:

<Name Highlight="false" Conflict="false">Name 1</Name>
<Name Highlight="false" Conflict="false">Name 2</Name>
<Name Highlight="true" Conflict="false">Name 3</Name>
<Name Highlight="false" Conflict="false">Name 4</Name>
<Name Highlight="false" Conflict="false">Name 5</Name>
<Name Highlight="true" Conflict="false">Name 3</Name>

The columns XML is like this:

<Columns>
    <Heading TextAlign="left" Width="11%">Date</Heading>
    <Heading TextAlign="left" Width="11%">Hall Attendant</Heading>
    <Heading TextAlign="left" Width="11%">Car Park</Heading>
    <Heading TextAlign="left" Width="11%">Sound</Heading>
    <Heading TextAlign="left" Width="11%">Platform</Heading>
    <Heading TextAlign="left" Width="11%">Mic Left</Heading>
    <Heading TextAlign="left" Width="11%">Mic Right</Heading>
    <Heading TextAlign="left" Width="11%">Chairman</Heading>
    <Heading TextAlign="left" Width="11%">Watchtower Reader</Heading>
</Columns>

For the output I was hoping to having for the assignments:

Assignment X, Assignment Y

on the same line with a comma separating them.

But what I am getting is:

Assignment X, Assignment Y,

I understand why that is happening. At first, I thought of using a <xsl:for-each select="Name[@Highlight='true']"> and then I could have used the position() value and if it was 1, just output the assignment otherwise output ", Assignment".

Whilst that would work, it falls over when I am trying to display the assignment description. I have to use the physical position of the name object in the AssignmentRow so that I locate the correct column heading value. If I use filtering with for-each I am going to lose those column index positions.

This is why i settled on looping all names so that I had the correct position value to use for looking up the assignment. The trade off is that I now do not know when I have located the first instance where Highlight is set to true.

So is there any way to suppress this trailing comma if it is present?

Upvotes: 1

Views: 58

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 117102

There are several ways you could approach this:

  1. Use a predicate in your xsl:for-each (as you say you thought of doing at first), and use count(preceding-sibling::Name) to calculate the index number.

  2. Test for the existence of following-sibling::Name[[@Highlight='true']" to detect the last node, and don't output the comma when it is.

  3. Use an interim variable to store the highlighted Names, along with their (original) position. Then process the variable.


I should add that options #1 and #2 are more expensive in terms of performance (requiring repeated testing along the sibling axes), while the 3rd option will require more coding.

Upvotes: 1

Related Questions