I need to start the delem (concept-expected output) after r4 (conbody- expected output), which is not happening - xslt-1.0

I need to start the delem (concept-expected output) after r4 (conbody- expected output), currently with respect to r4 mapping, conbody is wrapping the concept (delem).
Basically, I want r4 conbody to end before delem (concept) element.
I am stuck, Need help with the solution.
Input xml
<?xml version="1.0" encoding="UTF-8"?>
<specif>
<rtit>Test specif</rtit>
<r3>
<rtit>Test r3</rtit>
<r4>
<rtit>Test r4</rtit>
<p> para Test r4</p>
<delem>
<p>para Test delem</p>
</delem>
<r6>
<rtit>Test r6</rtit>
<p>para Test r6</p>
</r6>
</r4>
</r3>
</specif>
current output
<?xml version="1.0" encoding="UTF-8"?>
<concept>
<title>Test specif</title>
<conbody/>
<concept>
<title>Test r3</title>
<conbody/>
<concept>
<title>Test r4</title>
<conbody>
<p> para Test r4</p>
<concept>
<title></title>
<conbody> <p> para Test delem</p> </conbody>
</concept>
</conbody>
<concept>
<title>Test r6</title>
<conbody> <p> para Test r6</p> </conbody>
</concept>
</concept>
</concept>
</concept>
Expected output
<?xml version="1.0" encoding="UTF-8"?>
<concept>
<title>Test specif</title>
<conbody/>
<concept>
<title>Test r3</title>
<conbody/>
<concept>
<title>Test r4</title>
<conbody><p> para Test r4</p></conbody>
<concept>
<title></title>
<conbody> <p> para Test delem</p> </conbody>
</concept>
<concept>
<title>Test r6</title>
<conbody> <p> para Test r6</p> </conbody>
</concept>
</concept>
</concept>
</concept>
XSL
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="sb/body/specif"/>
</xsl:template>
<xsl:template match="specif">
<concept>
<xsl:attribute name="xsi:noNamespaceSchemaLocation" select="'techinfo.xsd'"/>
<xsl:choose>
<xsl:when test="not(#id)">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id ='')">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id !='')">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
</xsl:when>
</xsl:choose>
<xsl:attribute name="xml:lang">
<xsl:value-of select="'en'"/>
</xsl:attribute>
<xsl:apply-templates select="*[matches(local-name(),'r3')]"/>
</concept>
</xsl:template>
<xsl:template match="*[matches(local-name(),'r3')]">
<concept>
<xsl:choose>
<xsl:when test="not(#id)">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id ='')">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id !='')">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
</xsl:when>
</xsl:choose>
<xsl:attribute name="xml:lang">
<xsl:value-of select="'en'"/>
</xsl:attribute>
<title>
<xsl:for-each select="child::rtit">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
<xsl:apply-templates select="node()|#*|text()"/>
</xsl:for-each>
</title>
<conbody>
<xsl:apply-templates select="*[not(starts-with(local-name(),'r'))]"/>
</conbody>
<!-- apply recursive -->
<xsl:apply-templates select="*[matches(local-name(),'r4')]"/>
</concept>
</xsl:template>
<xsl:template match="*[matches(local-name(),'r4')]">
<concept>
<xsl:choose>
<xsl:when test="not(#id)">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id ='')">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id !='')">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
</xsl:when>
</xsl:choose>
<xsl:attribute name="xml:lang">
<xsl:value-of select="'en'"/>
</xsl:attribute>
<title>
<xsl:for-each select="child::rtit">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
<xsl:apply-templates select="node()|#*|text()"/>
</xsl:for-each>
</title>
<conbody>
<xsl:choose>
<xsl:when test="child::r5|r6|r7|r8|r9">
<xsl:apply-templates select="*[not(starts-with(local-name(),'r'))]"/>
</xsl:when>
<xsl:when test="child::delem">
<xsl:apply-templates select="*[not(starts-with(local-name(),'delem'))]"/>
</xsl:when>
</xsl:choose>
</conbody>
<!-- apply recursive -->
<xsl:choose>
<xsl:when test="child::r5|r6|r7|r8|r9">
<xsl:apply-templates select="*[matches(local-name(),'r[5-9]')]"/>
</xsl:when>
<xsl:when test="child::delem">
<xsl:apply-templates select="delem"/>
</xsl:when>
</xsl:choose>
</concept>
</xsl:template>
<!--tch on all nodes like r1, r2,r4,r5,r6 etc-->
<xsl:template match="*[matches(local-name(),'r[5-9]')]">
<concept>
<xsl:choose>
<xsl:when test="not(#id)">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id ='')">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id !='')">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
</xsl:when>
</xsl:choose>
<xsl:attribute name="xml:lang">
<xsl:value-of select="'en'"/>
</xsl:attribute>
<title>
<xsl:for-each select="child::rtit">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
<xsl:apply-templates select="node()|#*|text()"/>
</xsl:for-each>
</title>
<conbody>
<xsl:choose>
<xsl:when test="*[matches(local-name(),'r[5-9]')]">
<xsl:apply-templates select="*[not(starts-with(local-name(),'r'))]"/>
</xsl:when>
<xsl:when test="*[matches(local-name(),'delem')]">
<xsl:apply-templates select="*[not(starts-with(local-name(),'delem'))]"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="*[not(starts-with(local-name(),'r'))]"/>
</xsl:otherwise>
</xsl:choose>
</conbody>
<!-- apply recursive -->
<xsl:choose>
<xsl:when test="*[matches(local-name(),'r[5-9]')]">
<xsl:apply-templates select="*[matches(local-name(),'r[5-9]')]"/>
</xsl:when>
<xsl:when test="*[matches(local-name(),'delem')]">
<xsl:apply-templates select="*[matches(local-name(),'delem')]"/>
</xsl:when>
</xsl:choose>
</concept>
</xsl:template>
<xsl:template match="delem">
<xsl:choose>
<xsl:when test="*[matches(local-name(),'r[3-9]')]">
<concept>
<xsl:choose>
<xsl:when test="not(#id)">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id ='')">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id !='')">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
</xsl:when>
</xsl:choose>
<xsl:attribute name="xml:lang">
<xsl:value-of select="'en'"/>
</xsl:attribute>
<title>
<xsl:for-each select="child::rtit">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
<xsl:apply-templates select="node()|#*|text()"/>
</xsl:for-each>
</title>
<xsl:for-each select="child::subtitle">
<shortdesc>
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
<xsl:apply-templates select="node()|#*|text()"/>
</shortdesc>
</xsl:for-each>
<conbody>
<!-- the logic of #id/#group attributes is not clear -->
<xsl:apply-templates select="*[not(starts-with(local-name(),'r')) ]"/>
</conbody>
<!-- apply recursive -->
<xsl:apply-templates select="*[matches(local-name(),'r[3-9]')]"/>
</concept>
</xsl:when>
<xsl:when test="*[not(matches(local-name(),'r[3-9]'))]">
<concept>
<xsl:choose>
<xsl:when test="not(#id)">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id ='')">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id !='')">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
</xsl:when>
</xsl:choose>
<xsl:attribute name="xml:lang">
<xsl:value-of select="'en'"/>
</xsl:attribute>
<title>
<xsl:for-each select="child::rtit">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
<xsl:apply-templates select="node()|#*|text()"/>
</xsl:for-each>
</title>
<xsl:for-each select="child::subtitle">
<shortdesc>
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
<xsl:apply-templates select="node()|#*|text()"/>
</shortdesc>
</xsl:for-each>
<conbody>
<xsl:apply-templates/>
</conbody>
</concept>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="rtit"/>
</xsl:stylesheet>

Related

Template Name and call-template

i have xslt for change status transaction. i can change for template who was in scope at template name bodys. but the plan was when data on headers have failed some condition and the status for the template bodys in node TxRsnSts need change too. but i cant get the value from headers. how i can get the value from headers and submit on variable name TxRsnStsB.
This the XSLT script i make
<xsl:stylesheet version="1.0" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:ns1="urn:iso:std:iso:20022:tech:xsd:head.001.001.01" xmlns:ns2="urn:iso:std:iso:20022:tech:xsd:pacs.002.001.10" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="no" method="xml" omit-xml-declaration="yes"/>
<xsl:template match="/">
<ns:BusMsg xmlns:ns="urn:iso" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso ../../../xsd/phase1/MainCIHub.xsd">
<ns1:AppHdr>
<xsl:call-template name="headers">
<xsl:with-param name="CpyDplct" select="//BusMsg/AppHdr/CpyDplct"/>
<xsl:with-param name="PssblDplct" select="//BusMsg/AppHdr/PssblDplct"/>
<xsl:with-param name="Sgntr" select="//BusMsg/AppHdr/Sgntr"/>
</xsl:call-template>
</ns1:AppHdr>
<ns:Document>
<ns:FIToFIPmtStsRpt>
<xsl:call-template name="bodys">
<xsl:with-param name="CtgyPurpB" select="//BusMsg/Document/FItoFICstmrCdtTrf/CdtTrfTxInf/PmtTpInf/CtgyPurp/Prtry"/>
<xsl:with-param name="IntrBkSttlmAmtB" select="//BusMsg/Document/FItoFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt/Value"/>
<xsl:with-param name="CcyB" select="//BusMsg/Document/FItoFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt/Ccy"/>
</xsl:call-template>
</ns:FIToFIPmtStsRpt>
</ns:Document>
</ns:BusMsg>
</xsl:template>
<xsl:template name="headers">
<xsl:param name="CpyDplct"/>
<xsl:param name="PssblDplct"/>
<xsl:param name="Sgntr"/>
<xsl:variable name="flagCpyDplcts">
<xsl:choose>
<xsl:when test="$CpyDplct = ''"/>
<xsl:when test="string-length($CpyDplct) <= 35 and ($CpyDplct = 'CODU' or $CpyDplct = 'COPY' or $CpyDplct = 'DUPL')">
<xsl:value-of select="$CpyDplct"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:copy-of select="$CpyDplct"/>
</xsl:copy>
<xsl:value-of select="'U0002'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="flagPssblDplcts">
<xsl:choose>
<xsl:when test="$PssblDplct = ''"/>
<xsl:when test="string-length($PssblDplct) <= 35 and ($PssblDplct = 'true' or $PssblDplct = 'false')">
<xsl:value-of select="$PssblDplct"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:copy-of select="$PssblDplct"/>
</xsl:copy>
<xsl:value-of select="'U0002'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="flagSgntrs">
<xsl:choose>
<xsl:when test="$Sgntr = ''"/>
<xsl:when test="string-length($Sgntr) <= 35">
<xsl:value-of select="$Sgntr"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:copy-of select="$PssblDplct"/>
</xsl:copy>
<xsl:value-of select="'U0012'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<ns1:CpyDplct>
<xsl:value-of select="$flagCpyDplcts"/>
</ns1:CpyDplct>
<ns1:PssblDplct>
<xsl:value-of select="$flagPssblDplcts"/>
</ns1:PssblDplct>
<ns1:Sgntr>
<xsl:value-of select="$flagSgntrs"/>
</ns1:Sgntr>
</xsl:template>
<xsl:template name="bodys">
<xsl:param name="CtgyPurpB"/>
<xsl:param name="IntrBkSttlmAmtB"/>
<xsl:param name="CcyB"/>
<xsl:variable name="flagCtgyPurpBs">
<xsl:variable name="payT" select="substring($CtgyPurpB,1,3)"/>
<xsl:variable name="catP" select="substring($CtgyPurpB,4,2)"/>
<xsl:choose>
<xsl:when test="not(contains($payT,'010') or contains($payT,'011') or contains($payT,'019') or contains($payT,'110') or contains($payT,'510') or contains($payT,'610') or contains($payT,'710') or contains($payT,'720') or contains($payT,'000'))">
<xsl:value-of select="'U0002'"/>
</xsl:when>
<xsl:when test="not(contains($catP,'01') or contains($catP,'02') or contains($catP,'03') or contains($catP,'99'))">
<xsl:value-of select="'U0002'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$CtgyPurpB"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="flagIntrBkSttlmAmtBs">
<xsl:variable name="amount" select="substring-before($IntrBkSttlmAmtB,'.')"/>
<xsl:variable name="decimal" select="substring-after($IntrBkSttlmAmtB,'.')"/>
<xsl:choose>
<xsl:when test="not(fn:matches($IntrBkSttlmAmtB, '^[0-9.]*$'))">
<xsl:value-of select="'U0038'"/>
</xsl:when>
<xsl:when test="not(string-length($amount) <= 16)">
<xsl:value-of select="'U0038'"/>
</xsl:when>
<xsl:when test="not(string-length($decimal) <= 2)">
<xsl:value-of select="'U0038'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$IntrBkSttlmAmtB"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="flagCcyBs">
<xsl:choose>
<xsl:when test="not(fn:matches($CcyB, '^[a-zA-Z0-9]*$') and string-length($CcyB) <= 3)">
<xsl:value-of select="'U0038'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$CcyB"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<ns1:CtgyPurp>
<xsl:value-of select="$flagCtgyPurpBs"/>
</ns1:CtgyPurp>
<ns1:IntrBkSttlmAmt>
<xsl:value-of select="$flagIntrBkSttlmAmtBs"/>
</ns1:IntrBkSttlmAmt>
<ns1:Ccy>
<xsl:value-of select="$flagCcyBs"/>
</ns1:Ccy>
<xsl:variable name="TxRsnStsB">
<xsl:choose>
<xsl:when
test="contains($flagSgntrs, 'U0012') or contains($flagSgntrs, 'U0002') or contains($flagSgntrs, 'U0038') or contains($flagPssblDplcts, 'U0012') or contains($flagPssblDplcts, 'U0002') or contains($flagPssblDplcts, 'U0038') or contains($flagCpyDplcts, 'U0012') or contains($flagCpyDplcts, 'U0002') or contains($flagCpyDplcts, 'U0038') or contains($flagCtgyPurpBs, 'U0012') or contains($flagCtgyPurpBs, 'U0002') or contains($flagCtgyPurpBs, 'U0038') or contains($flagIntrBkSttlmAmtBs, 'U0012') or contains($flagIntrBkSttlmAmtBs, 'U0002') or contains($flagIntrBkSttlmAmtBs, 'U0038') or contains($flagCcyBs, 'U0012') or contains($flagCcyBs, 'U0002') or contains($flagCcyBs, 'U0038')">
<xsl:value-of select="'Decline'" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'Approve'" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<ns1:TxRsnSts><xsl:value-of select="$TxRsnStsB"/></ns1:TxRsnSts>
</xsl:template>
</xsl:stylesheet>
Your question is hard to understand.
If you want to reuse the variabels you have declared in headers inside body, you have two options:
Save the result of headers inside a variable and use that as a parameter in your call to bodys.
The other option is to declare those variables as globals like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:ns1="urn:iso:std:iso:20022:tech:xsd:head.001.001.01"
xmlns:ns2="urn:iso:std:iso:20022:tech:xsd:pacs.002.001.10"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="no" method="xml" omit-xml-declaration="yes"/>
<xsl:variable name="CpyDplct" select="//BusMsg/AppHdr/CpyDplct"/>
<xsl:variable name="PssblDplct" select="//BusMsg/AppHdr/PssblDplct"/>
<xsl:variable name="Sgntr" select="//BusMsg/AppHdr/Sgntr"/>
<xsl:variable name="flagCpyDplcts">
<xsl:choose>
<xsl:when test="$CpyDplct = ''"/>
<xsl:when test="string-length($CpyDplct) <= 35 and ($CpyDplct = 'CODU' or $CpyDplct = 'COPY' or $CpyDplct = 'DUPL')">
<xsl:value-of select="$CpyDplct"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:copy-of select="$CpyDplct"/>
</xsl:copy>
<xsl:value-of select="'U0002'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="flagPssblDplcts">
<xsl:choose>
<xsl:when test="$PssblDplct = ''"/>
<xsl:when test="string-length($PssblDplct) <= 35 and ($PssblDplct = 'true' or $PssblDplct = 'false')">
<xsl:value-of select="$PssblDplct"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:copy-of select="$PssblDplct"/>
</xsl:copy>
<xsl:value-of select="'U0002'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="flagSgntrs">
<xsl:choose>
<xsl:when test="$Sgntr = ''"/>
<xsl:when test="string-length($Sgntr) <= 35">
<xsl:value-of select="$Sgntr"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:copy-of select="$PssblDplct"/>
</xsl:copy>
<xsl:value-of select="'U0012'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:template match="/">
<ns:BusMsg xmlns:ns="urn:iso" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso ../../../xsd/phase1/MainCIHub.xsd">
<ns1:AppHdr>
<xsl:call-template name="headers"/>
</ns1:AppHdr>
<ns:Document>
<ns:FIToFIPmtStsRpt>
<xsl:call-template name="bodys">
<xsl:with-param name="CtgyPurpB" select="//BusMsg/Document/FItoFICstmrCdtTrf/CdtTrfTxInf/PmtTpInf/CtgyPurp/Prtry"/>
<xsl:with-param name="IntrBkSttlmAmtB" select="//BusMsg/Document/FItoFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt/Value"/>
<xsl:with-param name="CcyB" select="//BusMsg/Document/FItoFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt/Ccy"/>
</xsl:call-template>
</ns:FIToFIPmtStsRpt>
</ns:Document>
</ns:BusMsg>
</xsl:template>
<xsl:template name="headers">
<ns1:CpyDplct>
<xsl:value-of select="$flagCpyDplcts"/>
</ns1:CpyDplct>
<ns1:PssblDplct>
<xsl:value-of select="$flagPssblDplcts"/>
</ns1:PssblDplct>
<ns1:Sgntr>
<xsl:value-of select="$flagSgntrs"/>
</ns1:Sgntr>
</xsl:template>
<xsl:template name="bodys">
<xsl:param name="CtgyPurpB"/>
<xsl:param name="IntrBkSttlmAmtB"/>
<xsl:param name="CcyB"/>
<xsl:param name="header"/>
<xsl:variable name="flagCtgyPurpBs">
<xsl:variable name="payT" select="substring($CtgyPurpB,1,3)"/>
<xsl:variable name="catP" select="substring($CtgyPurpB,4,2)"/>
<xsl:choose>
<xsl:when test="not(contains($payT,'010') or contains($payT,'011') or contains($payT,'019') or contains($payT,'110') or contains($payT,'510') or contains($payT,'610') or contains($payT,'710') or contains($payT,'720') or contains($payT,'000'))">
<xsl:value-of select="'U0002'"/>
</xsl:when>
<xsl:when test="not(contains($catP,'01') or contains($catP,'02') or contains($catP,'03') or contains($catP,'99'))">
<xsl:value-of select="'U0002'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$CtgyPurpB"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="flagIntrBkSttlmAmtBs">
<xsl:variable name="amount" select="substring-before($IntrBkSttlmAmtB,'.')"/>
<xsl:variable name="decimal" select="substring-after($IntrBkSttlmAmtB,'.')"/>
<xsl:choose>
<xsl:when test="not(fn:matches($IntrBkSttlmAmtB, '^[0-9.]*$'))">
<xsl:value-of select="'U0038'"/>
</xsl:when>
<xsl:when test="not(string-length($amount) <= 16)">
<xsl:value-of select="'U0038'"/>
</xsl:when>
<xsl:when test="not(string-length($decimal) <= 2)">
<xsl:value-of select="'U0038'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$IntrBkSttlmAmtB"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="flagCcyBs">
<xsl:choose>
<xsl:when test="not(fn:matches($CcyB, '^[a-zA-Z0-9]*$') and string-length($CcyB) <= 3)">
<xsl:value-of select="'U0038'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$CcyB"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<ns1:CtgyPurp>
<xsl:value-of select="$flagCtgyPurpBs"/>
</ns1:CtgyPurp>
<ns1:IntrBkSttlmAmt>
<xsl:value-of select="$flagIntrBkSttlmAmtBs"/>
</ns1:IntrBkSttlmAmt>
<ns1:Ccy>
<xsl:value-of select="$flagCcyBs"/>
</ns1:Ccy>
<xsl:variable name="TxRsnStsB">
<xsl:choose>
<xsl:when test="contains($flagSgntrs, 'U0012') or contains($flagSgntrs, 'U0002') or contains($flagSgntrs, 'U0038') or contains($flagPssblDplcts, 'U0012') or contains($flagPssblDplcts, 'U0002') or contains($flagPssblDplcts, 'U0038') or contains($flagCpyDplcts, 'U0012') or contains($flagCpyDplcts, 'U0002') or contains($flagCpyDplcts, 'U0038') or contains($flagCtgyPurpBs, 'U0012') or contains($flagCtgyPurpBs, 'U0002') or contains($flagCtgyPurpBs, 'U0038') or contains($flagIntrBkSttlmAmtBs, 'U0012') or contains($flagIntrBkSttlmAmtBs, 'U0002') or contains($flagIntrBkSttlmAmtBs, 'U0038') or contains($flagCcyBs, 'U0012') or contains($flagCcyBs, 'U0002') or contains($flagCcyBs, 'U0038')">
<xsl:value-of select="'Decline'" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'Approve'" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<ns1:TxRsnSts><xsl:value-of select="$TxRsnStsB"/></ns1:TxRsnSts>
</xsl:template>
</xsl:stylesheet>

XSLT 1.0 Conditional Value

i have conditional like this:
<xsl:variable name="MsgIdBs">
<xsl:variable name="dateB" select="substring($MsgIdB,1,8)"/>
<xsl:variable name="biCodeB" select="substring($MsgIdB,9,8)"/>
<xsl:variable name="trTpB" select="substring($MsgIdB,17,3)"/>
<xsl:variable name="snB" select="substring($MsgIdB,20,8)"/>
<xsl:choose>
<xsl:when test="not(fn:matches($MsgIdB, '^[a-zA-Z0-9]*$') and string-length($MsgIdB) <= 35)">
<xsl:copy>
<xsl:copy-of select="$MsgIdB"/>
</xsl:copy>
<xsl:variable name="flag" select="'false'"/>
</xsl:when>
<xsl:when test="not(number(substring($dateB, 1, 4)) >= 1970 and number(substring($dateB, 5, 2)) <= 12 and number(substring($dateB, 7, 2)) <= 31)">
<xsl:copy>
<xsl:copy-of select="$MsgIdB"/>
</xsl:copy>
<xsl:variable name="flag" select="'false'"/>
</xsl:when>
<xsl:when test="not(contains($trTpB,'010') or contains($trTpB,'011') or contains($trTpB,'019') or contains($trTpB,'110') or contains($trTpB,'510') or contains($trTpB,'610') or contains($trTpB,'710') or contains($trTpB,'720') or contains($trTpB,'000'))">
<xsl:copy>
<xsl:copy-of select="$MsgIdB"/>
</xsl:copy>
<xsl:variable name="flag" select="'false'"/>
</xsl:when>
<xsl:when test="not(fn:matches($snB, '^\d+$'))">
<xsl:copy>
<xsl:copy-of select="$MsgIdB"/>
</xsl:copy>
<xsl:variable name="flag" select="'false'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$MsgIdB"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
and i have a variable to check value from variable name flag. but i always get value from otherwise. never get value from variable flag on conditional. the code like this:
<xsl:variable name="output">
<xsl:choose>
<xsl:when test="$flag = 'false'">
<ns2:TxSts>Not Deal</ns2:TxSts>
</xsl:when>
<xsl:otherwise>
<ns2:TxSts>Deal</ns2:TxSts>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
how i can get the value from variable name flag on conditional and compare base with variable output.
Create a seperate variable for flag. This will keep the flag varible in scope for use in following code.
<xsl:variable name="flag">
<xsl:variable name="dateB" select="substring($MsgIdB,1,8)"/>
<xsl:variable name="biCodeB" select="substring($MsgIdB,9,8)"/>
<xsl:variable name="trTpB" select="substring($MsgIdB,17,3)"/>
<xsl:variable name="snB" select="substring($MsgIdB,20,8)"/>
<xsl:choose>
<xsl:when test="not(number(substring($dateB, 1, 4)) >= 1970 and number(substring($dateB, 5, 2)) <= 12 and number(substring($dateB, 7, 2)) <= 31)">
<xsl:value-of select="'false'"/>
</xsl:when>
<xsl:when test="not(contains($trTpB,'010') or contains($trTpB,'011') or contains($trTpB,'019') or contains($trTpB,'110') or contains($trTpB,'510') or contains($trTpB,'610') or contains($trTpB,'710') or contains($trTpB,'720') or contains($trTpB,'000'))">
<xsl:value-of select="'false'"/>
</xsl:when>
<xsl:when test="not(fn:matches($snB, '^\d+$'))">
<xsl:value-of select="'false'"/>
</xsl:when>
</xsl:choose>
</xsl:variable>
Use the flag to create MsgIdBs.
<xsl:variable name="MsgIdBs">
<xsl:choose>
<xsl:when test="contains($flag, 'false)">
<xsl:copy>
<xsl:copy-of select="$MsgIdB"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$MsgIdB"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
Use the flag again to create output.
<xsl:variable name="output">
<xsl:choose>
<xsl:when test="contains($flag, 'false)">
<ns2:TxSts>Not Deal</ns2:TxSts>
</xsl:when>
<xsl:otherwise>
<ns2:TxSts>Deal</ns2:TxSts>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>

If the ID of 2 components are the same, how to add the suffix to the first ID as _first and _second for the 2nd ID using XSL

If the ID of 2 COMPONENT IS the same, I want to add the suffix to the first ID as _first and _second for the 2nd ID using XSL. When I am trying to fetch the 2nd ID of COMPONENT, both the 1st and 2nd ID are getting fetched.
This is a sample XML
<xml>
<root>
<SERVCAT CREATE-DATE="05/24/2016 04:45:40" LAST-MOD-DATE="05/24/2016 04:45:40" ID="G801" TITLE="801-Starting">
<CONFIGITEM CREATE-DATE="05/11/2016 17:09:34" LAST-MOD-DATE="05/11/2016 17:09:34" ID="G801_000" TITLE="000-G801_000_000_F_000000_202">
<SERVICEITEM CREATE-DATE="05/11/2016 17:09:34" LAST-MOD-DATE="05/11/2016 17:09:34" ID="G801_000_F" TITLE="F-Diagnostics by function">
<COMPONENT CREATE-DATE="05/24/2016 04:45:40" LAST-MOD-DATE="05/24/2016 04:45:40" ID="G801_000_000_F" TITLE="G801_000_000_F-Starting">
</COMPONENT>
</SERVICEITEM>
</CONFIGITEM>
<CONFIGITEM CREATE-DATE="05/11/2016 17:09:34" LAST-MOD-DATE="05/11/2016 17:09:34" ID="G801_000" TITLE="000-G801_000_000_F_000000_203">
<SERVICEITEM CREATE-DATE="05/11/2016 17:09:34" LAST-MOD-DATE="05/11/2016 17:09:34" ID="G801_000_F" TITLE="F-Diagnostics by function">
<COMPONENT CREATE-DATE="05/24/2016 04:45:40" LAST-MOD-DATE="05/24/2016 04:45:40" ID="G801_000_000_F" TITLE="G801_000_000_F-Starting">
</COMPONENT>
</SERVICEITEM>
</CONFIGITEM>
</SERVCAT>
</root>
</xml>
This is a sample XSL
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="componentsList" select="//COMPONENT"/>
<xsl:template match="COMPONENT">
<xsl:variable name="myComponentIdPHX" select="#ID"/>
<xsl:choose>
<xsl:when test="(count($componentsList[#ID=$myComponentIdPHX])=1)">
<COMPONENT CREATE-DATE="{#CREATE-DATE}" LAST-MOD-DATE="{#LAST-MOD-DATE}" ID="{#ID}" ID2="{#ID}_first" TITLE="{#TITLE}" >
<xsl:apply-templates />
</COMPONENT>
</xsl:when>
<xsl:when test="(count($componentsList[#ID=$myComponentIdPHX])=2)">
<COMPONENT CREATE-DATE="{#CREATE-DATE}" LAST-MOD-DATE="{#LAST-MOD-DATE}" ID="{#ID}" ID2="{#ID}_second" TITLE="{#TITLE}" >
<xsl:apply-templates />
</COMPONENT>
</xsl:when>
<xsl:otherwise>
<COMPONENT CREATE-DATE="{#CREATE-DATE}" LAST-MOD-DATE="{#LAST-MOD-DATE}" ID="{#ID}" ID2="{#ID}_others" TITLE="{#TITLE}" >
<xsl:apply-templates />
</COMPONENT>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Try this. You'll need to add a root node, if you want a well formed XML output.
<xsl:key name="myKey" match="COMPONENT" use="#ID"/>
<xsl:template match="COMPONENT">
<xsl:copy>
<xsl:apply-templates select="#CREATE-DATE" mode="add"/>
<xsl:apply-templates select="#LAST-MOD-DATE" mode="add"/>
<xsl:apply-templates select="#ID" mode="add"/>
<xsl:attribute name="id2">
<xsl:choose>
<xsl:when test="count(key('myKey',#ID)) = 1">
<xsl:value-of select="#ID"/>
</xsl:when>
<xsl:when test="generate-id(.) = generate-id(key('myKey',#ID)[1])">
<xsl:value-of select="concat(#ID, '_first')"/>
</xsl:when>
<xsl:when test="generate-id(.) = generate-id(key('myKey',#ID)[2])">
<xsl:value-of select="concat(#ID, '_second')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat(#ID, '_others')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:apply-templates select="#TITLE" mode="add"/>
<xsl:apply-templates select="node()" mode="add"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|#*" mode="add">
<xsl:copy>
<xsl:apply-templates select="node()|#*" mode="add"/>
</xsl:copy>
</xsl:template>

Otherwise XSLT1.0 - correct output

I´ve a problem at my xslt.
Here it is:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="GRP">
<xsl:copy>
<!--copy the data from ADD - ST to the GRP so it can be used in the mapping to set the delivery address from end customer-->
<xsl:for-each select ="./ADD">
<xsl:if test="./QUALIFIER='ST'">
<xsl:copy-of select="PARTY_NAME_1"/>
<xsl:copy-of select="STREET_1"/>
<xsl:copy-of select="CITY"/>
<xsl:copy-of select="POSTAL_CODE"/>
<xsl:copy-of select="COUNTRY_CODE"/>
</xsl:if>
<xsl:choose>
<xsl:when test="./QUALIFIER='CN'">
<CONTACT_NUMBER>
<xsl:value-of select="CONTACT/NUMBER"/>
</CONTACT_NUMBER>
</xsl:when>
<xsl:otherwise>
<xsl:if test="./QUALIFIER='ST'">
<CONTACT_NUMBER>
<xsl:value-of select="CONTACT/NUMBER"/>
</CONTACT_NUMBER>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<!--copy all other nodes-->
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Can you tell me, whats my mistake at my xml?
At my code i get Contact_Number 2 times.
I just like one of them... If Contact at CN - use this, otherwise use from ST.
-> If contact at CN and ST use CN.
Edit: xml:
<SEEDELFOR>
<GRP>
<ADD>
<QUALIFIER>CN</QUALIFIER>
<IDENTIFIER></IDENTIFIER>
<AGENCY_CODE></AGENCY_CODE>
<PARTY_NAME_1></PARTY_NAME_1>
<STREET_1></STREET_1>
<CITY></CITY>
<POSTAL_CODE></POSTAL_CODE>
<COUNTRY_CODE></COUNTRY_CODE>
<CONTACT>
<QUALIFIER></QUALIFIER>
<NUMBER>1111111</NUMBER>
</CONTACT>
</ADD>
<ADD>
<QUALIFIER>ST</QUALIFIER>
<IDENTIFIER></IDENTIFIER>
<AGENCY_CODE></AGENCY_CODE>
<PARTY_NAME_1></PARTY_NAME_1>
<STREET_1></STREET_1>
<CITY></CITY>
<POSTAL_CODE></POSTAL_CODE>
<CONTACT>
<QUALIFIER></QUALIFIER>
<NUMBER>2222222</NUMBER>
</CONTACT>
</ADD>
</GRP>
</SEEDELFOR>
How can i correct my xslt?
I hope you can help me.
Best regards
Julian
One of the way you can achieve this is, rewriting the template GRP as following:
<xsl:template match="GRP">
<xsl:copy>
<!--copy the data from ADD - ST to the GRP so it can be used in the mapping
to set the delivery address from end customer -->
<xsl:variable name="contact_ST">
<xsl:for-each select="./ADD">
<xsl:if test="./QUALIFIER='ST'">
<CONTACT_NUMBER>
<xsl:value-of select="CONTACT/NUMBER" />
</CONTACT_NUMBER>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="contact_CN">
<xsl:for-each select="./ADD">
<xsl:if test="./QUALIFIER='CN'">
<CONTACT_NUMBER>
<xsl:value-of select="CONTACT/NUMBER" />
</CONTACT_NUMBER>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:for-each select="./ADD">
<xsl:if test="./QUALIFIER='ST'">
<xsl:copy-of select="PARTY_NAME_1" />
<xsl:copy-of select="STREET_1" />
<xsl:copy-of select="CITY" />
<xsl:copy-of select="POSTAL_CODE" />
<xsl:copy-of select="COUNTRY_CODE" />
</xsl:if>
</xsl:for-each>
<xsl:choose>
<xsl:when test="$contact_CN != ''">
<xsl:copy-of select="$contact_CN" />
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$contact_ST" />
</xsl:otherwise>
</xsl:choose>
<!--copy all other nodes -->
<xsl:apply-templates select="#* | node()" />
</xsl:copy>
</xsl:template>
Consider the following simplified example:
<xsl:template match="GRP">
<xsl:copy>
<!-- other code, if necessary-->
<xsl:variable name="cn" select="ADD[QUALIFIER='CN']" />
<xsl:variable name="st" select="ADD[QUALIFIER='ST']" />
<CONTACT_NUMBER>
<xsl:choose>
<xsl:when test="$cn">
<xsl:value-of select="$cn/CONTACT/NUMBER"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$st/CONTACT/NUMBER"/>
</xsl:otherwise>
</xsl:choose>
</CONTACT_NUMBER>
<!-- more code, if necessary-->
</xsl:copy>
</xsl:template>

XSLT1.0 replace multiple occurences of char with <br />

Have the following template that I use with xsl:call-template, but I need to use it to replace a ~ with <br />. I can get it to work with none HTML replacements but not when I try to use <br /> or &NewLine; or
. Any suggestions:
<xsl:template name="replace-substring">
<xsl:param name="original"/>
<xsl:param name="substring"/>
<xsl:param name="replacement" select="''"/>
<xsl:variable name="first">
<xsl:choose>
<xsl:when test="contains($original, $substring)" >
<xsl:value-of select="substring-before($original, $substring)" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$original"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="middle">
<xsl:choose>
<xsl:when test="contains($original, $substring)">
<xsl:value-of select="$replacement" />
</xsl:when>
<xsl:otherwise>
<xsl:text></xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="last">
<xsl:choose>
<xsl:when test="contains($original, $substring)">
<xsl:choose>
<xsl:when test="contains(substring-after($original, $substring),
$substring)">
<xsl:call-template name="replace-substring">
<xsl:with-param name="original">
<xsl:value-of select="substring-after($original, $substring)"/>
</xsl:with-param>
<xsl:with-param name="substring">
<xsl:value-of select="$substring"/>
</xsl:with-param>
<xsl:with-param name="replacement">
<xsl:value-of select="$replacement"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-after($original, $substring)" />
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:text></xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="concat($first, $middle, $last)"/>
</xsl:template>
It's hard to tell what's going on with the first, middle, and last variables but you should be able to just use a literal <br/> in your param...
XML
<test>one~two~three</test>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="test">
<xsl:copy>
<xsl:call-template name="replace-char"/>
</xsl:copy>
</xsl:template>
<xsl:template name="replace-char">
<xsl:param name="char" select="'~'"/>
<xsl:param name="replacement"><br/></xsl:param>
<xsl:param name="string" select="."/>
<xsl:variable name="remaining" select="substring-after($string,$char)"/>
<xsl:value-of select="substring-before(concat($string,$char),$char)"/>
<xsl:if test="contains($string,$char)">
<xsl:copy-of select="$replacement"/>
</xsl:if>
<xsl:if test="$remaining">
<xsl:call-template name="replace-char">
<xsl:with-param name="string" select="$remaining"/>
<xsl:with-param name="char" select="$char"/>
<xsl:with-param name="replacement" select="$replacement"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Output
<test>one<br/>two<br/>three</test>