Search code examples
xslt-2.0apply-templates

Transform only the last element of XML and copy the rest in XSLT


I have an XML like below -

   <root>
    <row>
     <col1>16</col1>
      <col2>466</col2>
        <col3>144922</col3>
        <col4>0</col4>
        <col5>5668</col5>
        <col6>475</col6>
    </row>
</root>

The number of columns can vary inside the root element. It can also be up to col9. My requirement is to modify the last column and copy others as it is for an incoming XML.

I have something like this till now where I am assigning the value to used as the last element in a variable and then trying to call it when the last position is reached-

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs"
    version="2.0">

    <xsl:param name="line88.field2" />
    <xsl:param name="rec16.col2" />

    <xsl:variable name="col3">
        <xsl:choose>
            <xsl:when test="$rec16.col2 ='165'">
                <xsl:value-of select="'Y'"/>
            </xsl:when>
            <xsl:when>
             ------
            <xsl:when>
        </xsl:choose>

    </xsl:variable>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"></xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="row[position() = last()]">
        <col9>
            <xsl:call-template name="AnotherTemplate">
                <xsl:with-param name="inputData">
                    <xsl:value-of select="$col3" />
                </xsl:with-param>
            </xsl:call-template>
        </col9>
    </xsl:template>
    <xsl:template name="AnotherTemplate">
        <xsl:param name="inputData"></xsl:param>
        <xsl:value-of select="$inputData" />
    </xsl:template>

</xsl:stylesheet>

But this is not working for me. Just giving me one column with the modified value.Please help. The desired outcome should be as below where the last column has the value from the variable.

<root>
<row>
        <col1>16</col1>
        <col2>466</col2>
        <col3>144922</col3>
        <col4>0</col4>
        <col5>5668</col5>
        <col6>Y</col6>
 </row>
</root>

Solution

  • Without knowing your whole XSLT code. You can use this row template:

    <xsl:template match="row/*[starts-with(local-name(),'col') and position() = last()]">
        <xsl:element name="{concat('col',position() div 2)}">
            <xsl:call-template name="AnotherTemplate">
                <xsl:with-param name="inputData">
                    <xsl:value-of select="$col3" />
                </xsl:with-param>
            </xsl:call-template>
        </xsl:element>
    </xsl:template>
    

    It replaces the last col? element by the given value (the result of the xsl:call-template code).