0

I have to generate the output in sequence and so I wanted to know how to access the variable defined under For-each loop/If condition and then value of select inside another for loop.

As per my example how to access partn and date3? Please help and suggest. what is the concept for achieving the same..I have tried with-param as well, but didn't work for me.

XSLT:

     <?xml version="1.0" encoding="UTF-8"?>

    <xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:func="myfunc" 
 xmlns:xs="http://www.w3.org/2001/XMLSchema" 
   xmlns:fn="http://www.w3.org/2005/xpath-functions" >
<xsl:output method="text" encoding="utf-8" />
<xsl:output omit-xml-declaration="yes" />
<xsl:param name="break" select="'&#xA;'" />
      <xsl:template match="ZGS/ID">
    <xsl:for-each select="E1">   
        <xsl:if test="PA = 'CE'">
            <xsl:variable name="partn" select="PAN"/>
        </xsl:if>
    </xsl:for-each>
    <xsl:for-each select="E13">   
        <xsl:if test="ID = 033">
            <xsl:variable name="date3" 
     select="substring(DAT,3,8)"/>
        </xsl:if>
    </xsl:for-each>
    <xsl:for-each select="E1E">
        <xsl:text>823</xsl:text>
        <xsl:text>03</xsl:text>
        <xsl:for-each select="E1ED">
            <xsl:if test="QU = 012 ">
                <xsl:value-of select="BEL"/>  
            </xsl:if>
        </xsl:for-each>
        <xsl:value-of select="$partn"/>
        <xsl:value-of select="$date3"/>
    </xsl:for-each>
</xsl:template>

INPUT:

     <?xml version='1.0' encoding='utf-8'?>
    <ZGS>
  <ID BEGIN="1">
<E1 SEGMENT="1">
    <PA>AG</PA>
    <NAME>ABC</NAME>
    <SP>E</SP>
    <AND>0004</AND>
</E1>
<E1 SEGMENT="1">
    <PA>RE</PA>
    <PAN>IUIOP</PAN>
    <NAME>ABC1</NAME>
    <SP>EQ</SP>
    <AND>0005</AND>
    <EKA3 SEGMENT="1">
     <QU>009</QU>
    </EKA3>
</E1>
<E1 SEGMENT="1">
    <PA>CE</PA>
    <PAN>PODW</PAN>
    <NAME>ABC2</NAME>
    <SP>EP</SP>
    <AND>0006</AND>
</E1>
<E13 SEGMENT="1">
    <ID>001</ID>
    <DAT>20190329</DAT>
</E13>
<E13 SEGMENT="1">
    <ID>002</ID>
    <DAT>20190429</DAT>
</E13>
<E13 SEGMENT="1">
    <IDD>033</IDD>
    <DAT>20190529</DAT>
</E13>
<E1E>
<E1ED>
</E1ED>
<E1ED>
</E1ED>
</E1E>

1 Answer 1

1

In XSLT, variables once declared/defined, they cannot be changed. And exists only in the loop they are defined.

You might not need the xsl:for-each loop here. Instead the variables can be globally defined, so that you can use them where you want in your xslt.

You can try the following:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:func="myfunc"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">

<xsl:output method="text" encoding="utf-8" />
<xsl:output omit-xml-declaration="yes" />
<xsl:param name="break" select="'&#xA;'" />

<xsl:variable name="partn" select="/ZGS/ID/E1[PA = 'CE']/PAN" />
<xsl:variable name="date3" select="substring(/ZGS/ID/E13[ID = '033']/DAT,3,8)" />

<xsl:template match="ZGS/ID">
    <xsl:for-each select="E1E">
        <xsl:text>823</xsl:text>
        <xsl:text>03</xsl:text>

        <xsl:for-each select="E1ED">
            <xsl:if test="QU = 012 ">
                <xsl:value-of select="BEL" />
            </xsl:if>
        </xsl:for-each>

        <xsl:value-of select="$partn" />
        <xsl:value-of select="$date3" />
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/jyRYYiu

Using xsl:param, it can be achieved as

<xsl:param name="partn" select="/ZGS/ID/E1[PA = 'CE']/PAN" />
<xsl:param name="date3" select="substring(/ZGS/ID/E13[ID = '033']/DAT,3,8)" />

<xsl:template match="ZGS/ID">
    <xsl:for-each select="E1E">
        <xsl:text>823</xsl:text>
        <xsl:text>03</xsl:text>

        <xsl:for-each select="E1ED">
            <xsl:if test="QU = 012 ">
                <xsl:value-of select="BEL" />
            </xsl:if>
        </xsl:for-each>

        <xsl:for-each select="$partn">
            <xsl:value-of select="." />
        </xsl:for-each>

        <xsl:value-of select="$date3" />
    </xsl:for-each>
</xsl:template>

https://xsltfiddle.liberty-development.net/jyRYYiu/1

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for your inputs. So you mean we can replace the for each we I have applied for repeated chunks with the variable declaration in the mentioned way.Please correct my understanding.
@kuhujain : Yes. In updated link I have added one extra block where E1/PA is CE and it's PAN value is EXTRAPAN. Note that it will combine the value of repeated chunks. If you need to process on each value, you can add for-each in the global variables declared. Thanks.
Yes,so instead of writing <xsl:for-each select="E1"><xsl:if test="PA = 'CE'"><xsl:variable name="partn" select="PAN"/></xsl:if></xsl:for-each> we can write - <xsl:variable name="partn" select="/ZGS/ID/E1[PA = 'CE']/PAN" /> Both works in a same way, but in case of variable we can access where we want in XSLT.Becoz, as of now I have written so many for each and was unable to access the variables outside of it.This is working as expected.
Also, can we write global variable inside template as well ?
can we write global variable inside template as well ? : The variable is global if it's declared as a top-level element, and local if it's declared within a template. If you define a variable in template, it can be used within the scope of that template only. OR you can pass it as parameter to another template.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.