Search code examples
xsltxslt-2.0xslt-3.0

XSLT:Sort issue when using the key field


I have an issue while sorting LuLineItem where I need to sort it when its corresponding Iden/IdenValue, where IdenType=OCC1 is repeating in another LuLineItem, then based on Idenvalue, where Identype=OCC2, we need to do the sorting.

My XSLT is not giving correct sequence, Please review it once.

Input: IdenValue=1234 in first LULineItem where identype=OCC1 is not repeating, but IdenValue=4567 is repeating in second and third LULineItem, so we need to sort LULineItem based on IdenValue where IdenType=OCC2

<SBD>
    <SBDH>
        <Field1> value1</Field1>
    </SBDH>
    <rAdvice>
        <LULineItem>
            <UnitIden>
                <CCode>
                    <SSCC>32101</SSCC>
                </CCode>
            </UnitIden>
            <CLine number="1">
                <cIIden>
                    <ntig>00000000000000</ntig>
                    <Iden>
                        <IdenValue>1234</IdenValue>
                        <IdenType>OCC1</IdenType>
                    </Iden>             
                    <Iden>
                        <IdenValue>XYZ</IdenValue>
                        <IdenType>OCC2</IdenType>
                    </Iden>
                </cIIden>
            </CLine>
        </LULineItem>
        <LULineItem>
            <UnitIden>
                <CCode>
                    <SSCC>543857</SSCC>
                </CCode>
            </UnitIden>
            <CLine number="2">
                <cIIden>
                    <ntig>00000000000000</ntig>
                    <Iden>
                        <IdenValue>4567</IdenValue>
                        <IdenType>OCC1</IdenType>
                    </Iden>
                    <Iden>
                        <IdenValue>BCD</IdenValue>
                        <IdenType>OCC2</IdenType>
                    </Iden>
                </cIIden>
            </CLine>
            <PO>
                <dReference>
                    <CreatorIden>094832</CreatorIden>
                    <cOwner>
                        <nlg>0000000000000</nlg>
                    </cOwner>
                </dReference>
            </PO>
        </LULineItem>
        <LULineItem>
            <UnitIden>
                <CCode>
                    <SSCC>32109</SSCC>
                </CCode>
            </UnitIden>
            <CLine number="3">
                <cIIden>
                    <ntig>00000000000000</ntig>
                    <Iden>
                        <IdenValue>4567</IdenValue>
                        <IdenType>OCC1</IdenType>
                    </Iden>
                    <Iden>
                        <IdenValue>3109</IdenValue>
                        <IdenType>OCC3</IdenType>
                    </Iden>
                    <Iden>
                        <IdenValue>ACD</IdenValue>
                        <IdenType>OCC2</IdenType>
                    </Iden>
                </cIIden>
            </CLine>
        </LULineItem>
    </rAdvice>
</SBD>

Desired output:

<SBD>
     <SBDH>
        <Field1> value1</Field1>
    </SBDH>
    <rAdvice>
        <LULineItem>
            <UnitIden>
                <CCode>
                    <SSCC>32101</SSCC>
                </CCode>
            </UnitIden>
            <CLine number="1">
                <cIIden>
                    <ntig>00000000000000</ntig>
                    <Iden>
                        <IdenValue>1234</IdenValue>
                        <IdenType>OCC1</IdenType>
                    </Iden>
                    <Iden>
                        <IdenValue>XYZ</IdenValue>
                        <IdenType>OCC2</IdenType>
                    </Iden>
                </cIIden>
            </CLine>
        </LULineItem>
        <LULineItem>
            <UnitIden>
                <CCode>
                    <SSCC>32109</SSCC>
                </CCode>
            </UnitIden>
            <CLine number="3">
                <cIIden>
                    <ntig>00000000000000</ntig>
                    <Iden>
                        <IdenValue>4567</IdenValue>
                        <IdenType>OCC1</IdenType>
                    </Iden>
                    <Iden>
                        <IdenValue>3109</IdenValue>
                        <IdenType>OCC3</IdenType>
                    </Iden>
                    <Iden>
                        <IdenValue>ACD</IdenValue>
                        <IdenType>OCC2</IdenType>
                    </Iden>
                </cIIden>
            </CLine>
        </LULineItem>
        <LULineItem>
            <UnitIden>
                <CCode>
                    <SSCC>543857</SSCC>
                </CCode>
            </UnitIden>
            <CLine number="2">
                <cIIden>
                    <ntig>00000000000000</ntig>
                    <Iden>
                        <IdenValue>4567</IdenValue>
                        <IdenType>OCC1</IdenType>
                    </Iden>
                    <Iden>
                        <IdenValue>BCD</IdenValue>
                        <IdenType>OCC2</IdenType>
                    </Iden>
                </cIIden>
            </CLine>
            <PO>
                <dReference>
                    <CreatorIden>094832</CreatorIden>
                    <cOwner>
                        <nlg>0000000000000</nlg>
                    </cOwner>
                </dReference>
            </PO>
        </LULineItem>
    </rAdvice>
</SBD>

XSLT I used is below:

<?xml version="1.0" encoding="utf-8"?>
<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="#all"
  expand-text="yes">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="rAdvice">
      <xsl:for-each select="LULineItem">
           <xsl:sort select="CIIden/Iden[IdenType='OCC2']/IdenValue" data-type="text" order="ascending"/>
        <xsl:copy-of select="."/>
      </xsl:for-each>
   
  </xsl:template> 

</xsl:stylesheet>

Please review it once


Solution

  • Based on your comments and your question I now think you want something like

    <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="#all">
      
      <xsl:output method="xml" indent="yes"/>
      
      <xsl:mode on-no-match="shallow-copy"/>
      
      <xsl:template match="rAdvice">
        <xsl:copy>
          <xsl:for-each-group select="LULineItem" group-by="CLine/cIIden/Iden[IdenType='OCC1']/IdenValue">
            <xsl:sequence select="sort(current-group(), (), function($l) { $l/CLine/cIIden/Iden[IdenType='OCC2']/IdenValue })" />
          </xsl:for-each-group>    
        </xsl:copy>
      </xsl:template> 
    
    </xsl:stylesheet>
    

    Example fiddle that seems to have the desired result.