XSLT - Passing variables using Tunnel not working as expected

Viewed 59

I am pretty new to XSLT. I am using XSLT 2.0 tunnel parameter for one of my scenario - I need to get the first value of <last_mod_dt_TS> in a group and put in all nodes where <request_Id> is same.

Below is the sample XML I am using -

<?xml version='1.0' encoding='UTF-8'?>
<root>
  <row>
    <request_Id>4007</request_Id>
    <req_tp>Action</req_tp>
    <last_mod_dt_TS>2021-09-07T07:38:11.000</last_mod_dt_TS>
  </row>
  <row>
    <request_Id>4007</request_Id>
    <req_tp>Action</req_tp>
    <last_mod_dt_TS>2021-10-10T17:32:44.000</last_mod_dt_TS>
  </row>
</root>

XSLT as follows -

<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet 
  version="2.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  exclude-result-prefixes="#all">
  <xsl:output indent="yes"/>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>  
  <xsl:template match="root">
    <xsl:copy>
      <xsl:for-each-group select="row" group-by="request_Id">
      <xsl:apply-templates select="current-group()">
        <xsl:with-param name="slaStart" select="current-group()[1]/last_mod_dt_TS" tunnel="yes"/>
      </xsl:apply-templates>
    </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>  
  <xsl:template match="last_mod_dt_TS">
    <xsl:param name="slaStart" tunnel="yes"/>
    <xsl:copy>
      <xsl:value-of select="slaStart"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

My expected output -

<?xml version='1.0' encoding='UTF-8'?>
<root>
  <row>
    <request_Id>4007</request_Id>
    <req_tp>Action</req_tp>
    <last_mod_dt_TS>2021-09-07T07:38:11.000</last_mod_dt_TS>
  </row>
  <row>
    <request_Id>4007</request_Id>
    <req_tp>Action</req_tp>
    <last_mod_dt_TS>2021-09-07T07:38:11.000</last_mod_dt_TS>
  </row>
</root>

Using my XSLT -

<root>
   <row>
      <request_Id>4007</request_Id>
      <req_tp>Action</req_tp>
      <last_mod_dt_TS/>
  </row>
   <row>
      <request_Id>4007</request_Id>
       <req_tp>Action</req_tp>
      <last_mod_dt_TS/>
  </row>
</root>

I am not sure why the XSLT is not working as expected. Any help is much appreciated. Thank you.

2 Answers

Use <xsl:value-of select="$slaStart"/> to output and reference the variable value.

Note that you don't need the parameter and the tunneling at all. The current group and current grouping key are passed unchanged through calls of xsl:apply-templates - so you can do simply:

<xsl:template match="/root">
    <xsl:copy>
        <xsl:for-each-group select="row" group-by="request_Id">
            <xsl:apply-templates select="current-group()"/>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template> 

and then:

<xsl:template match="last_mod_dt_TS">
    <xsl:copy>
        <xsl:value-of select="current-group()[1]/last_mod_dt_TS"/>
    </xsl:copy>
</xsl:template>
Related