Subject: deleting the continuous commas
Posted By: mrame Post Date: 7/21/2008 4:58:00 PM
im trying to get a list of values from set of rows. i separate the result with comma. but if the value is null, an ampty comma is obtained. how to overcome this issue.

see my code below:
<xsl:template match="rattrow[.//UsedByProduct = $implSource][.//TL1Attribute]" mode="positional">
        <xsl:param name="tl1c"/>

        <xsl:variable name="currRow" select="."/>
        
        <xsl:for-each select=".[.//UsedByProduct = $implSource]">
            
                    <xsl:choose>
                        <xsl:when test="$tl1c = 'Retrieve'">
                            <xsl:for-each
                                select=".[matches($currRow//TL1Commands[@cmdType='RetrieveIn'], '^[O|Y].*$')]">
                                <xsl:text>[&lt;</xsl:text>
                                <xsl:value-of select=".//TL1Attribute"/>
                                <xsl:text>&gt;]</xsl:text>
                            </xsl:for-each>

                            <xsl:for-each
                                select=".[matches($currRow//TL1Commands[@cmdType='RetrieveIn'], '^M.*$')]">
                                <xsl:text>&lt;</xsl:text>
                                <xsl:value-of select="$currRow//TL1Attribute"/>
                                <xsl:text>&gt;</xsl:text>
                            </xsl:for-each>
                        </xsl:when>

                        <xsl:when test="$tl1c = 'Read'">
                            <xsl:for-each
                                select=".[matches($currRow//TL1Commands[@cmdType='ReadIn'], '^[O|Y].*$')]">
                                <xsl:text>[&lt;</xsl:text>
                                <xsl:value-of select="$currRow//TL1Attribute"/>
                                <xsl:text>&gt;]</xsl:text>
                            </xsl:for-each>

                            <xsl:for-each
                                select=".[matches($currRow//TL1Commands[@cmdType='ReadIn'], '^M.*$')]">
                                <xsl:text>&lt;</xsl:text>
                                <xsl:value-of select="$currRow//TL1Attribute"/>
                                <xsl:text>&gt;</xsl:text>
                            </xsl:for-each>
                        </xsl:when>

                        <xsl:otherwise>
                            <xsl:for-each
                                select=".[matches($currRow//TL1Commands[@cmdType=$tl1c], '^[O|Y].*$')]">
                                <xsl:text>[&lt;</xsl:text>
                                <xsl:value-of select="$currRow//TL1Attribute"/>
                                <xsl:text>&gt;]</xsl:text>
                            </xsl:for-each>

                            <xsl:for-each
                                select=".[matches($currRow//TL1Commands[@cmdType=$tl1c], '^M.*$')]">
                                <xsl:text>&lt;</xsl:text>
                                <xsl:value-of select="$currRow//TL1Attribute"/>
                                <xsl:text>&gt;</xsl:text>
                            </xsl:for-each>
                        </xsl:otherwise>
                    </xsl:choose>
                  </xsl:for-each>
                  
                  <xsl:if test = "not(position()=last())">
                    <xsl:text>, </xsl:text>
                  </xsl:if>
    </xsl:template>

If the above template, checks a list of rows, then it produces the output as as shown below:
<AID>, <AID>, ,
I can omit the last comma, but again if the last()-1 is also empty, then an empty comma is produced.

any help is appreciated



Reply By: mhkay Reply Date: 7/21/2008 9:51:54 PM
There's some very strange code here.

This:

<xsl:for-each select=".[.//UsedByProduct = $implSource]">

is equivalent to

<xsl:if test=".//UsedByProduct = $implSource">

which is surely clearer. Moreover, that condition seems to be always true, because if it weren't true then the template wouldn't match.

Similarly most people would write

<xsl:for-each                             select=".[matches($currRow//TL1Commands[@cmdType='RetrieveIn'], '^M.*$')]">

as <xsl:if test="matches(....)">

Moreover the three branches of the xsl:choose are so similar that they could surely be turned into a function with a single parameter.

As for the actual question: position()=last() within a template rule is probably not a particularly good idea, because its meaning depends on the set of things selected by the corresponding apply-templates call, which you haven't shown us. If you want to use position()=last(), then in the apply-templates that invokes this template rule you should only select the elements you want to process: that is, you should filter out those that are (to use your term) "null".

Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer's Reference
Reply By: mrame Reply Date: 7/23/2008 12:46:01 PM
thank you. i have solved this thro' recursive template.


Go to topic 72690

Return to index page 1