dsi
dsi

Reputation: 3369

remove last comma in XSLT

using XSLT 1.0.

<xsl:for-each select="*">
    <xsl:variable name="xxxx" select="@name" />
    <xsl:if test="../../../../fieldMap/field[@name=$xxxx]">...
        <xsl:if test="position() != last()">////this is not work correctly as last() number is actual last value of for loop and position() is based on if condition.
            <xsl:text>,</xsl:text>
        </xsl:if>
    </xsl:if>
</xsl:for-each>

can you suggest me how can i remove last ',' here ?

Upvotes: 4

Views: 6135

Answers (3)

Tim C
Tim C

Reputation: 70638

position() and last() should be based on the loop, and not the xsl:if. What I think you are saying is that you are actually wanting to check if this is the last element for which the xsl:if is true, as such an element may not actually be the last element in the loop.

I would suggest combining your xsl:for-each and xsl:if into one, and selecting only those elements for which the condition is true. That way you should then be able to check the position in the way you were expecting

<xsl:for-each select="*[@name = ../../../../fieldMap/field/@name]">

    <xsl:if test="position() != last()">
         <xsl:text>,</xsl:text>
    </xsl:if>
</xsl:for-each>

Upvotes: 11

ashok vaddiraju
ashok vaddiraju

Reputation: 1

Translate, replace, split-join won't work in XSLT.I implemented a simple way which is working fine in my XSLT

Sample code:

  <xsl:variable name="ErrorCPN">
    <xsl:if test="count(/DATA_DS/G_1)>0 and count(/DATA_DS/CPN)>0">
      <xsl:for-each select="$BIPReportCPN/ns3:BIPCPN/ns3:BIPEachCPNDelimitedValue">
        <xsl:variable name="BIPEachCPNDelimitedValue" select="."/>
        <xsl:if test="count(/DATA_DS/G_1[CPN=$BIPEachCPNDelimitedValue]/CPN)=0">
          <xsl:value-of select="concat($BIPEachCPNDelimitedValue,',')"/>
        </xsl:if>
      </xsl:for-each>
    </xsl:if>
  </xsl:variable>
  <xsl:value-of select="substring($ErrorCPN,1,string-length($ErrorCPN)-1)"/>
</xsl:if> 

I created one variable and inside if and for each conditions implemented, for every loop required value is concatenated with a comma, at the end of the loop one extra comma will be there which is not required to us. So, we can take the substring and eliminate last comma.

Otherwise use the sample code and try.

Upvotes: 0

LarsH
LarsH

Reputation: 28004

You can change your inner if to:

    <xsl:if test="not(following-sibling::*[
                   @name = ../../../../fieldMap/field/@name])">
        <xsl:text>,</xsl:text>
    </xsl:if>

BTW this works because of "general comparisons". I.e.

A = B

is true if any node selected by A is equal to (has same value as) any node selected by B.

For the sake of DRY, I would probably put ../../../../fieldMap/field/@name into a variable and declare it before the for-each loop begins:

<xsl:variable name="fieldNames" select="../../../../fieldMap/field/@name" />
<xsl:for-each select="*">
    <xsl:if test="$fieldNames = @name">...
        <xsl:if test="not(following-sibling::*[@name = $fieldNames])">
            <xsl:text>,</xsl:text>
        </xsl:if>
    </xsl:if>
</xsl:for-each>

Again, $fieldNames can be a nodeset of multiple attribute nodes, and when we say $fieldNames = @name, we are asking whether the value of @name equals the value of any node in $fieldNames.

Upvotes: 1

Related Questions