xslt-2.0xslt-3.0

XSLT Grouping issue based on condition


i am trying to write an XSLT which will group all relevant SG9 segment based on SG9 field A_51 where A_50= KAR (xpath: INVR/SG9/SG11/SG14/FFR/C506[A_50='KAR']/A_51 in input xml), after grouping for each group we need to add <TNU>segment in the last, my xslt is not giving exact result, Please check once

Input sample

<?xml version="1.0" encoding="UTF-8"?>
<INVR>
    <HNU_S>
        <FIELD1>0002</FIELD1>
    </HNU_S>
    <MGB_S>
        <FIELD1>2410458</FIELD1>
    </MGB_S> 
    <GS2>
        <NODE>
            <FIELD2>SU</FIELD2>           
        </NODE>
    </GS2>
    <SG9>
        <NIL_S>
            <FIELD1>4141</FIELD1>     
        </NIL_S>     
        <SG11>                      
            <SG14>
                <FFR>
                    <C506>
                        <A_50>KAR</A_50>
                        <A_51>1234</A_51>
                    </C506>
                </FFR>
            </SG14>
        </SG11>
    </SG9>
       <SG9>
        <NIL_S>
            <FIELD1>43636</FIELD1>     
        </NIL_S>     
        <SG11>                      
            <SG14>
                <FFR>
                    <C506>
                        <A_50>KAR</A_50>
                        <A_51>4567</A_51>
                    </C506>
                </FFR>
            </SG14>
        </SG11>
    </SG9>
       <SG9>
        <NIL_S>
            <FIELD1>65757</FIELD1>     
        </NIL_S>     
        <SG11>                      
            <SG14>
                <FFR>
                    <C506>
                        <A_50>KKR</A_50>
                        <A_51>1234</A_51>
                    </C506>
                </FFR>
            </SG14>
        </SG11>
    </SG9>
       <SG9>
        <NIL_S>
            <FIELD1>14145</FIELD1>     
        </NIL_S>     
        <SG11>                      
            <SG14>
                <FFR>
                    <C506>
                        <A_50>KKR</A_50>
                        <A_51>4567</A_51>
                    </C506>
                </FFR>
            </SG14>
        </SG11>
    </SG9>
    
    
    <TNU>
        <FIELD1>330</FIELD1>      
    </TNU>
</INVR>

output sample

<?xml version="1.0" encoding="UTF-8"?>
<INVR>
    <HNU_S>
        <FIELD1>0002</FIELD1>
    </HNU_S>
    <MGB_S>
        <FIELD1>2410458</FIELD1>
    </MGB_S> 
    <GS2>
        <NODE>
            <FIELD2>SU</FIELD2>           
        </NODE>
    </GS2>
    <group>
    <SG9>
        <NIL_S>
            <FIELD1>4141</FIELD1>     
        </NIL_S>     
        <SG11>                      
            <SG14>
                <FFR>
                    <C506>
                        <A_50>KAR</A_50>
                        <A_51>1234</A_51>
                    </C506>
                </FFR>
            </SG14>
        </SG11>
    </SG9>
     <SG9>
        <NIL_S>
            <FIELD1>65757</FIELD1>     
        </NIL_S>     
        <SG11>                      
            <SG14>
                <FFR>
                    <C506>
                        <A_50>KKR</A_50>
                        <A_51>1234</A_51>
                    </C506>
                </FFR>
            </SG14>
        </SG11>
    </SG9>
    
     <TNU>
        <FIELD1>330</FIELD1>      
    </TNU>
    </group>
    <group>
       <SG9>
        <NIL_S>
            <FIELD1>43636</FIELD1>     
        </NIL_S>     
        <SG11>                      
            <SG14>
                <FFR>
                    <C506>
                        <A_50>KAR</A_50>
                        <A_51>4567</A_51>
                    </C506>
                </FFR>
            </SG14>
        </SG11>
    </SG9>
      
       <SG9>
        <NIL_S>
            <FIELD1>14145</FIELD1>     
        </NIL_S>     
        <SG11>                      
            <SG14>
                <FFR>
                    <C506>
                        <A_50>KKR</A_50>
                        <A_51>4567</A_51>
                    </C506>
                </FFR>
            </SG14>
        </SG11>
    </SG9>
      <TNU>
        <FIELD1>330</FIELD1>      
    </TNU>
    </group>
    
  
</INVR>

XSLT I used

<xsl:stylesheet xmlns:xsl="
http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="SG9">
        <G_SG9>
            <xsl:apply-templates select="*[not(self::SG9)]"/>
            <xsl:for-each-group select="SG9" group-by="/INVR/SG9/SG11/SG14/FFR/C506[A_50='KAR']/A_51">
                <group>
                    <xsl:copy-of select="current-group()"/>
                </group>
            </xsl:for-each-group>
        </G_SG9>
    </xsl:template>
</xsl:stylesheet>


Solution

  • If I understand correctly what you are looking to do, then I think you would create an empty template for SG9 and then have a template matching on TNU that selects and groups the SG9 elements and emits the TNU at the end of each group:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
        <xsl:output method="xml" indent="yes"/>
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
        
        <xsl:template match="SG9"/>
        
        <xsl:template match="TNU">
            <xsl:variable name="TNU" select="."/>
            <xsl:for-each-group select="/INVR/SG9" group-by="SG11/SG14/FFR/C506/A_51">
                <group>
                    <xsl:copy-of select="current-group()"/>
                    <xsl:copy-of select="$TNU"/>
                </group>
            </xsl:for-each-group> 
        </xsl:template>
        
    </xsl:stylesheet>
    

    Which produces the following output:

    <INVR>
       <HNU_S>
          <FIELD1>0002</FIELD1>
       </HNU_S>
       <MGB_S>
          <FIELD1>2410458</FIELD1>
       </MGB_S>
       <GS2>
          <NODE>
             <FIELD2>SU</FIELD2>
          </NODE>
       </GS2>
       <group>
          <SG9>
             <NIL_S>
                <FIELD1>4141</FIELD1>
             </NIL_S>
             <SG11>
                <SG14>
                   <FFR>
                      <C506>
                         <A_50>KAR</A_50>
                         <A_51>1234</A_51>
                      </C506>
                   </FFR>
                </SG14>
             </SG11>
          </SG9>
          <SG9>
             <NIL_S>
                <FIELD1>65757</FIELD1>
             </NIL_S>
             <SG11>
                <SG14>
                   <FFR>
                      <C506>
                         <A_50>KKR</A_50>
                         <A_51>1234</A_51>
                      </C506>
                   </FFR>
                </SG14>
             </SG11>
          </SG9>
          <TNU>
             <FIELD1>330</FIELD1>
          </TNU>
       </group>
       <group>
          <SG9>
             <NIL_S>
                <FIELD1>43636</FIELD1>
             </NIL_S>
             <SG11>
                <SG14>
                   <FFR>
                      <C506>
                         <A_50>KAR</A_50>
                         <A_51>4567</A_51>
                      </C506>
                   </FFR>
                </SG14>
             </SG11>
          </SG9>
          <SG9>
             <NIL_S>
                <FIELD1>14145</FIELD1>
             </NIL_S>
             <SG11>
                <SG14>
                   <FFR>
                      <C506>
                         <A_50>KKR</A_50>
                         <A_51>4567</A_51>
                      </C506>
                   </FFR>
                </SG14>
             </SG11>
          </SG9>
          <TNU>
             <FIELD1>330</FIELD1>
          </TNU>
       </group>
    </INVR>