Xslt: Transform Nodes By Comparing Their Child Nodes
Solution 1:
I hesitate whether to post this at all, because you seem to be a beginner at XSLT and this is a complex solution to a complex problem. It may take you quite some time to wrap your head around this.
How this works:
In the first pass, we generate a pmt
element for each PmtInf
element in your input XML, and populate it with a string that contains a name/value pair for each node (element or attribute) descendant of the current PmtInf
. In the given example, each such pmt
element would look similar to:
<pmt id="idp1696">[PmtInfId:asd][PmtMtd:TRF][BtchBookg:false][PmtTpInf:NORMtest][InstrPrty:NORM][SvcLvl:test][Prtry:test][ReqdExctnDt:date][Dbtr:somethingaddr 1][Nm:something][PstlAdr:addr 1][AdrLine:addr 1]</pmt>
In the next step we apply Muenchian grouping to the pmt
nodes generated in the first pass. For each distinct pmt
node, we create a PmtInf
element and populate it with:
the contents of the corresponding
PmtInf
element, exceptCdtTrfTxInf
;a copy of all
CdtTrfTxInf
elements from all the members of the group.
XSLT 1.0
<xsl:stylesheetversion="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"xmlns:ns0="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03"xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03"xmlns:exsl="http://exslt.org/common"exclude-result-prefixes="ns0"extension-element-prefixes="exsl"><xsl:outputmethod="xml"version="1.0"encoding="UTF-8"indent="yes"/><xsl:strip-spaceelements="*"/><xsl:keyname="pmt"match="ns0:pmt"use="." /><xsl:keyname="PmtInf"match="ns0:PmtInf"use="generate-id()" /><xsl:variablename="input"select="/" /><!-- identity transform --><xsl:templatematch="@*|node()"><xsl:copy><xsl:apply-templatesselect="@*|node()"/></xsl:copy></xsl:template><xsl:templatematch="ns0:CstmrCdtTrfInitn"><!-- first pass --><xsl:variablename="first-pass-rtf"><xsl:apply-templatesselect="ns0:PmtInf"mode="gen-key"/></xsl:variable><xsl:variablename="first-pass"select="exsl:node-set($first-pass-rtf)" /><!-- output --><xsl:copy><xsl:copy-ofselect="ns0:GrpHdr"/><!-- for each distinct pmt --><xsl:for-eachselect="$first-pass/ns0:pmt[count(. | key('pmt', .)[1]) = 1]"><xsl:variablename="id"select="@id" /><xsl:variablename="ids"select="key('pmt', .)/@id" /><PmtInf><!-- switch context back to XML input --><xsl:for-eachselect="$input"><xsl:copy-ofselect="key('PmtInf', $id)/*[not(self::ns0:CdtTrfTxInf)]"/><xsl:copy-ofselect="key('PmtInf', $ids)/ns0:CdtTrfTxInf"/></xsl:for-each></PmtInf></xsl:for-each></xsl:copy></xsl:template><xsl:templatematch="ns0:PmtInf"mode="gen-key"><pmtid="{generate-id()}"><xsl:apply-templatesselect="@*|*"mode="gen-key"/></pmt></xsl:template><xsl:templatematch="@*|node()"mode="gen-key"><xsl:text>[</xsl:text><xsl:value-ofselect="name()"/><xsl:text>:</xsl:text><xsl:value-ofselect="."/><xsl:text>]</xsl:text><xsl:apply-templatesselect="@*|*"mode="gen-key"/></xsl:template><xsl:templatematch="ns0:CdtTrfTxInf"mode="gen-key"/></xsl:stylesheet>
Post a Comment for "Xslt: Transform Nodes By Comparing Their Child Nodes"