Reputation: 3369
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
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
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
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