my requirement is to get common K18 segments where its having similar ALF and OND fields, with different subnodes P04Y,P04Z,P04,P03, i need to group them under its parent K18 segment. for example in my input first two K18 has same child nodes except P03, 3rd K18 has different child nodes, we need to club them together.
also we need to check P01/TP1 has same ID and RAS then we need to club PT2 under same TP1 segment.
Input:
<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
<LEAV ONE="1">
<EDI SEGMENT="1">
<FIELD1>EDI</FIELD1>
</EDI>
<AK1 SEGMENT="1">
<VW>RS</VW>
</AK1>
<K18 SEGMENT="1">
<ALF>001</ALF>
<OND>ACF</OND>
<P04Y SEGMENT="1">
<K_1>VALUE1</K_1>
</P04Y>
<P04Z SEGMENT="1">
<REGN>HU</REGN>
</P04Z>
<P04 SEGMENT="1">
<B_DOC>810</B_DOC>
</P04>
<P03 SEGMENT="1">
<FIELD1>X</FIELD1>
<SEQ>10</SEQ>
<RNTAM>VALUE1</RNTAM>
</P03>
</K18>
<K18 SEGMENT="1">
<ALF>001</ALF>
<OND>ACF</OND>
<P04Y SEGMENT="1">
<K_1>VALUE1</K_1>
</P04Y>
<P04Z SEGMENT="1">
<REGN>HU</REGN>
</P04Z>
<P04 SEGMENT="1">
<B_DOC>810</B_DOC>
</P04>
<P03 SEGMENT="1">
<FIELD1>X</FIELD1>
<SEQ>20</SEQ>
<RNTAM>VALUE2</RNTAM>
</P03>
</K18>
<K18 SEGMENT="1">
<ALF>001</ALF>
<OND>ACF</OND>
<P04Y SEGMENT="1">
<K_1>new value</K_1>
</P04Y>
<P04Z SEGMENT="1">
<REGN>new</REGN>
</P04Z>
<P04 SEGMENT="1">
<B_DOC>new value</B_DOC>
</P04>
<P03 SEGMENT="1">
<FIELD1>X</FIELD1>
<SEQ>20</SEQ>
<RNTAM>VALUE2</RNTAM>
</P03>
</K18>
<K18 SEGMENT="1">
<ALF>001</ALF>
<OND>FCB</OND>
<P04Y SEGMENT="1">
<K_1>VALUE1</K_1>
</P04Y>
<P04Z SEGMENT="1">
<REGN>HU</REGN>
</P04Z>
<P04 SEGMENT="1">
<B_DOC>810</B_DOC>
</P04>
<P03 SEGMENT="1">
<FIELD1>X</FIELD1>
<SEQ>000020</SEQ>
<RNTAM>VALUE213</RNTAM>
</P03>
</K18>
<K28 SEGMENT="1">
<BCOUN>ES</BCOUN>
</K28>
<P01 SEGMENT="1">
<FIELD1>10</FIELD1>
<FIELD2>1</FIELD2>
<P02 SEGMENT="1">
<FIELD1>001</FIELD1>
</P02>
<TP1 SEGMENT="1">
<ID>01</ID>
<RAS>X</RAS>
<PT2 SEGMENT="1">
<LINE>VALUE1</LINE>
</PT2>
</TP1>
<TP1 SEGMENT="1">
<ID>01</ID>
<RAS>X</RAS>
<PT2 SEGMENT="1">
<LINE>VALUE2</LINE>
</PT2>
</TP1>
</P01>
<P01 SEGMENT="1">
<FIELD1>10</FIELD1>
<FIELD2>1</FIELD2>
<P02 SEGMENT="1">
<FIELD1>001</FIELD1>
</P02>
<TP1 SEGMENT="1">
<ID>01</ID>
<RAS>X</RAS>
<PT2 SEGMENT="1">
<LINE>VALUE1</LINE>
</PT2>
</TP1>
<TP1 SEGMENT="1">
<ID>01</ID>
<RAS>X</RAS>
<PT2 SEGMENT="1">
<LINE>VALUE2</LINE>
</PT2>
</TP1>
<TP1 SEGMENT="1">
<ID>02</ID>
<RAS>X</RAS>
<PT2 SEGMENT="1">
<LINE>VALUE2</LINE>
</PT2>
</TP1>
</P01>
<PS01 SEGMENT="1">
<FIELD1>VALUE</FIELD1>
</PS01>
</LEAV>
</ROOT>
** Desired Output:**
<ROOT>
<LEAV ONE="1">
<EDI SEGMENT="1">
<FIELD1>EDI</FIELD1>
</EDI>
<AK1 SEGMENT="1">
<VW>RS</VW>
</AK1>
<K18 SEGMENT="1">
<ALF>001</ALF>
<OND>ACF</OND>
<P04Y SEGMENT="1">
<K_1>VALUE1</K_1>
</P04Y>
<P04Y SEGMENT="1">
<K_1>new value</K_1>
</P04Y>
<P04Z SEGMENT="1">
<REGN>HU</REGN>
</P04Z>
<P04Z SEGMENT="1">
<REGN>new</REGN>
</P04Z>
<P04 SEGMENT="1">
<B_DOC>810</B_DOC>
</P04>
<P04 SEGMENT="1">
<B_DOC>new value</B_DOC>
</P04>
<P03 SEGMENT="1">
<FIELD1>X</FIELD1>
<SEQ>10</SEQ>
<RNTAM>VALUE1</RNTAM>
</P03>
<P03 SEGMENT="1">
<FIELD1>X</FIELD1>
<SEQ>20</SEQ>
<RNTAM>VALUE2</RNTAM>
</P03>
</K18>
<K18 SEGMENT="1">
<ALF>001</ALF>
<OND>FCB</OND>
<P04Y SEGMENT="1">
<K_1>VALUE1</K_1>
</P04Y>
<P04Z SEGMENT="1">
<REGN>HU</REGN>
</P04Z>
<P04 SEGMENT="1">
<B_DOC>810</B_DOC>
</P04>
<P03 SEGMENT="1">
<FIELD1>X</FIELD1>
<SEQ>000020</SEQ>
<RNTAM>VALUE213</RNTAM>
</P03>
</K18>
<K28 SEGMENT="1">
<BCOUN>ES</BCOUN>
</K28>
<P01 SEGMENT="1">
<FIELD1>10</FIELD1>
<FIELD2>1</FIELD2>
<P02 SEGMENT="1">
<FIELD1>001</FIELD1>
</P02>
<TP1 SEGMENT="1">
<ID>01</ID>
<RAS>X</RAS>
<PT2 SEGMENT="1">
<LINE>VALUE1</LINE>
</PT2>
<PT2 SEGMENT="1">
<LINE>VALUE2</LINE>
</PT2>
</TP1>
</P01>
<P01 SEGMENT="1">
<FIELD1>10</FIELD1>
<FIELD2>1</FIELD2>
<P02 SEGMENT="1">
<FIELD1>001</FIELD1>
</P02>
<TP1 SEGMENT="1">
<ID>01</ID>
<RAS>X</RAS>
<PT2 SEGMENT="1">
<LINE>VALUE1</LINE>
</PT2>
<PT2 SEGMENT="1">
<LINE>VALUE2</LINE>
</PT2>
</TP1>
<TP1 SEGMENT="1">
<ID>02</ID>
<RAS>X</RAS>
<PT2 SEGMENT="1">
<LINE>VALUE2</LINE>
</PT2>
</TP1>
</P01>
<PS01 SEGMENT="1">
<FIELD1>VALUE</FIELD1>
</PS01>
</LEAV>
</ROOT>
** XSLT I used is below:**
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" expand-text="yes">
<xsl:template match="LEAV">
<xsl:copy>
<xsl:apply-templates select="@*, * except (K18, K28)"/>
<xsl:for-each-group select="K18" composite="yes" group-by="ALF, OND">
<xsl:copy>
<xsl:apply-templates select="@*, ALF, OND"/>
<xsl:for-each-group select="current-group()!* except (current-group()!(ALF, OND))" composite="yes" group-by="node-name(), @*, *">
<xsl:sequence select="."/>
</xsl:for-each-group>
</xsl:copy>
</xsl:for-each-group>
<xsl:apply-templates select="K28"/>
</xsl:copy>
</xsl:template>
<xsl:template match="LEAV">
<xsl:copy>
<xsl:apply-templates select="@*, * except (P01, PS01)"/>
<xsl:for-each-group select="P01/TP11" composite="yes" group-by="ID, RAS">
<xsl:copy>
<xsl:apply-templates select="@*, ID,RAS"/>
<xsl:for-each-group select="current-group()!* except (current-group()!(ID,RAS))" composite="yes" group-by="node-name(), @*, *">
<xsl:sequence select="."/>
</xsl:for-each-group>
</xsl:copy>
</xsl:for-each-group>
<xsl:apply-templates select="P01,PS01"/>
</xsl:copy>
</xsl:template>
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
</xsl:stylesheet>
The stylesheet
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
expand-text="yes">
<xsl:template match="LEAV">
<xsl:copy>
<xsl:apply-templates select="@*, * except (K18, K28)"/>
<xsl:for-each-group select="K18" composite="yes" group-by="ALF, OND">
<xsl:copy>
<xsl:apply-templates select="@*, ALF, OND"/>
<xsl:for-each-group select="current-group()!* except (current-group()!(ALF, OND))" composite="yes" group-by="node-name(), @*, *">
<xsl:sequence select="."/>
</xsl:for-each-group>
</xsl:copy>
</xsl:for-each-group>
<xsl:apply-templates select="K28"/>
</xsl:copy>
</xsl:template>
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
</xsl:stylesheet>
seems to give the wanted result for your input sample, I am, however, not sure, I have understood your full requirements, the sole sample doesn't explain them detailed enough.
As for you edited XML input sample with additional elements and additional requirements, your attempt to use two templates for LEAV
doesn't make sense, what might lead you in the right direction is
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
expand-text="yes">
<xsl:template match="LEAV">
<xsl:copy>
<xsl:apply-templates select="@*, K18/preceding-sibling::*[not(self::K18)]"/>
<xsl:for-each-group select="K18" composite="yes" group-by="ALF, OND">
<xsl:copy>
<xsl:apply-templates select="@*, ALF, OND"/>
<xsl:for-each-group select="current-group()!* except (current-group()!(ALF, OND))" composite="yes" group-by="node-name(), @*, *">
<xsl:sequence select="."/>
</xsl:for-each-group>
</xsl:copy>
</xsl:for-each-group>
<xsl:apply-templates select="K18/following-sibling::*[not(self::K18)]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="P01">
<xsl:copy>
<xsl:apply-templates select="@*, TP1/preceding-sibling::*[not(self::TP1)]"/>
<xsl:for-each-group select="TP1" composite="yes" group-by="ID, RAS">
<xsl:copy>
<xsl:apply-templates select="@*, ID, RAS"/>
<xsl:for-each-group select="current-group()!* except (current-group()!(ID, RAS))" composite="yes" group-by="node-name(), @*, *">
<xsl:sequence select="."/>
</xsl:for-each-group>
</xsl:copy>
</xsl:for-each-group>
<xsl:apply-templates select="TP1/following-sibling::*[not(self::TP1)]"/>
</xsl:copy>
</xsl:template>
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
</xsl:stylesheet>
Give that a try and post feedback.