Merge functionality of two xsl files into a single file (not a xsl import or include issue)

Posted by anuamb on Stack Overflow See other posts from Stack Overflow or by anuamb
Published on 2011-01-10T07:34:24Z Indexed on 2011/01/10 9:53 UTC
Read the original article Hit count: 452

Filed under:
|
|

I have two xsl files; both of them perform different tasks on source xml one after another. Now I need a single xsl file which will actually perform both these tasks in single file (its not an issue of xsl import or xsl include):


say my source xml is:
<LIST_R7P1_1> <R7P1_1> <LVL2> <ORIG_EXP_PRE_CONV>#+# <EXP_AFT_CONV>abc <GUARANTEE_AMOUNT>#+# <CREDIT_DER/> </LVL2> <LVL21> <AZ>#+# <BZ>bz1 <AZ>az2 <BZ>#+# <CZ/> </LVL21> </R7P1_1> </LIST_R7P1_1>

My first xsl (tr1.xsl) removes all nodes whose value is blank or null:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:if test=". != '' or ./@* != ''">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:if>

<xsl:template>

</xsl:stylesheet>



The output here is

<LIST_R7P1_1> <R7P1_1> <LVL2> <ORIG_EXP_PRE_CONV>#+# <EXP_AFT_CONV>abc <GUARANTEE_AMOUNT>#+# </LVL2> <LVL21> <AZ>#+# <BZ>bz1 <AZ>az2 <BZ>#+# </LVL21> </R7P1_1> </LIST_R7P1_1>




And my second xsl (tr2.xsl) does a global replace (of #+# with text blank'') on the output of first xsl:


<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template name="globalReplace">

<xsl:param name="outputString"/>

<xsl:param name="target"/>

<xsl:param name="replacement"/>

<xsl:choose>

<xsl:when test="contains($outputString,$target)">

  <xsl:value-of select=
    "concat(substring-before($outputString,$target),
           $replacement)"/>
  <xsl:call-template name="globalReplace">
    <xsl:with-param name="outputString" 
         select="substring-after($outputString,$target)"/>
    <xsl:with-param name="target" select="$target"/>
    <xsl:with-param name="replacement" 
         select="$replacement"/>
  </xsl:call-template>
</xsl:when>
<xsl:otherwise>
  <xsl:value-of select="$outputString"/>
</xsl:otherwise>

</xsl:choose>

</xsl:template>

<xsl:template match="text()">

<xsl:template match="@*|*">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>




So my final output is


<LIST_R7P1_1> <R7P1_1> <LVL2> <ORIG_EXP_PRE_CONV> <EXP_AFT_CONV>abc <GUARANTEE_AMOUNT> </LVL2> <LVL21> <AZ> <BZ>bz1 <AZ>az2 <BZ> </LVL21> </R7P1_1> </LIST_R7P1_1>



My concern is that instead of these two xsl (tr1.xsl and tr2.xsl) I only need a single xsl (tr.xsl) which gives me final output?

Say when I combine these two as

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="@*|node()">

<xsl:if test=". != '' or ./@* != ''">

  <xsl:copy>

    <xsl:apply-templates select="@*|node()"/>

  </xsl:copy>

</xsl:if>

<xsl:template name="globalReplace">

<xsl:param name="outputString"/>

<xsl:param name="target"/>

<xsl:param name="replacement"/>

<xsl:choose>

<xsl:when test="contains($outputString,$target)">

  <xsl:value-of select=
    "concat(substring-before($outputString,$target),
           $replacement)"/>
  <xsl:call-template name="globalReplace">
    <xsl:with-param name="outputString" 
         select="substring-after($outputString,$target)"/>
    <xsl:with-param name="target" select="$target"/>
    <xsl:with-param name="replacement" 
         select="$replacement"/>
  </xsl:call-template>
</xsl:when>
<xsl:otherwise>
  <xsl:value-of select="$outputString"/>
</xsl:otherwise>

</xsl:choose>

</xsl:template>

<xsl:template match="text()">

<xsl:call-template name="globalReplace">

<xsl:with-param name="outputString" select="."/>

<xsl:with-param name="target" select="'#+#'"/>

<xsl:with-param name="replacement" select="''"/>

</xsl:call-template>

</xsl:template>

<xsl:template match="@|">

<xsl:copy>

<xsl:apply-templates select="@*|node()"/>

</xsl:copy>

</xsl:template>

</xsl:stylesheet>



it outputs:

<LIST_R7P1_1> <R7P1_1> <LVL2> <ORIG_EXP_PRE_CONV> <EXP_AFT_CONV>abc <GUARANTEE_AMOUNT> <CREDIT_DER/> </LVL2> <LVL21> <AZ> <BZ>bz1 <AZ>az2 <BZ> <CZ/> </LVL21> </R7P1_1> </LIST_R7P1_1>


Only replacement is performed but not null/blank node removal.

© Stack Overflow or respective owner

Related posts about xslt

Related posts about xsltprocessor