Home > Back-end >  XSLT - Passing variables using Tunnel not working as expected
XSLT - Passing variables using Tunnel not working as expected

Time:10-12

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.

CodePudding user response:

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

CodePudding user response:

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