sortingselectxsltcopyapply-templates

XSLT copy then sort element, duplicates sorted element


I am trying to sort the E1EDK33 element by "TSRFO_CONSIGNEE" However when doing so I get the original E1EDK33 elements plus the newly sorted elements in the end.

Here is my example file:

<SHPMNT06>
    <IDOC BEGIN="1">
        <EDI_DC40 SEGMENT="1">
            <TABNAM>EDI_DC40</TABNAM>
        </EDI_DC40>
        <E1EDT20 SEGMENT="1">
            <DeliveryStops>6</DeliveryStops>
            <E1EDT22 SEGMENT="1">
                <VSART_BEZ>LKW</VSART_BEZ>
            </E1EDT22>
            <E1EDK33 SEGMENT="1">
                <TSNUM>0001</TSNUM>
                <TSRFO>0001</TSRFO>
                <TSRFO_CONSIGNEE>0003</TSRFO_CONSIGNEE>
            </E1EDK33>
            <E1EDK33 SEGMENT="1">
                <TSNUM>0002</TSNUM>
                <TSRFO>0002</TSRFO>
                <TSRFO_CONSIGNEE>0002</TSRFO_CONSIGNEE>
            </E1EDK33>
            <E1EDK33 SEGMENT="1">
                <TSNUM>0003</TSNUM>
                <TSRFO>0003</TSRFO>
                <TSRFO_CONSIGNEE>0001</TSRFO_CONSIGNEE>
            </E1EDK33>
            <E1ETD01 SEGMENT="1">
                <DGMDDAT>20220321</DGMDDAT>
            </E1ETD01>
        </E1EDT20>
    </IDOC>
</SHPMNT06>

my xslt file:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
       <xsl:output omit-xml-declaration="yes" indent="yes" method="xml"/>
       <xsl:template match="node()|@*">
             <xsl:copy>
                    <xsl:apply-templates select="@*|node()"/>
             </xsl:copy>
       </xsl:template>
       <xsl:template match="E1EDT20">
             <xsl:copy>
                    <xsl:apply-templates select="@*"/>
                    <xsl:apply-templates select="*"/>
                    <xsl:apply-templates select="E1EDK33">
                           <xsl:sort select="TSRFO_CONSIGNEE" data-type="number" order="ascending"/>
                    </xsl:apply-templates>
             </xsl:copy>
       </xsl:template>
</xsl:stylesheet>

Result file:

<SHPMNT06>
    <IDOC BEGIN="1">
        <EDI_DC40 SEGMENT="1">
            <TABNAM>EDI_DC40</TABNAM>
        </EDI_DC40>
        <E1EDT20 SEGMENT="1">
            <DeliveryStops>6</DeliveryStops>
            <E1EDT22 SEGMENT="1">
                <VSART_BEZ>LKW</VSART_BEZ>
            </E1EDT22>
            <E1EDK33 SEGMENT="1">
                <TSNUM>0001</TSNUM>
                <TSRFO>0001</TSRFO>
                <TSRFO_CONSIGNEE>0003</TSRFO_CONSIGNEE>
            </E1EDK33>
            <E1EDK33 SEGMENT="1">
                <TSNUM>0002</TSNUM>
                <TSRFO>0002</TSRFO>
                <TSRFO_CONSIGNEE>0002</TSRFO_CONSIGNEE>
            </E1EDK33>
            <E1EDK33 SEGMENT="1">
                <TSNUM>0003</TSNUM>
                <TSRFO>0003</TSRFO>
                <TSRFO_CONSIGNEE>0001</TSRFO_CONSIGNEE>
            </E1EDK33>
            <E1ETD01 SEGMENT="1">
                <DGMDDAT>20220321</DGMDDAT>
            </E1ETD01>
            <E1EDK33 SEGMENT="1">
                <TSNUM>0003</TSNUM>
                <TSRFO>0003</TSRFO>
                <TSRFO_CONSIGNEE>0001</TSRFO_CONSIGNEE>
            </E1EDK33>
            <E1EDK33 SEGMENT="1">
                <TSNUM>0002</TSNUM>
                <TSRFO>0002</TSRFO>
                <TSRFO_CONSIGNEE>0002</TSRFO_CONSIGNEE>
            </E1EDK33>
            <E1EDK33 SEGMENT="1">
                <TSNUM>0001</TSNUM>
                <TSRFO>0001</TSRFO>
                <TSRFO_CONSIGNEE>0003</TSRFO_CONSIGNEE>
            </E1EDK33>
        </E1EDT20>
    </IDOC>
</SHPMNT06>

What I want to see is this:

<SHPMNT06>
    <IDOC BEGIN="1">
        <EDI_DC40 SEGMENT="1">
            <TABNAM>EDI_DC40</TABNAM>
        </EDI_DC40>
        <E1EDT20 SEGMENT="1">
            <DeliveryStops>6</DeliveryStops>
            <E1EDT22 SEGMENT="1">
                <VSART_BEZ>LKW</VSART_BEZ>
            </E1EDT22>
            <E1EDK33 SEGMENT="1">
                <TSNUM>0003</TSNUM>
                <TSRFO>0003</TSRFO>
                <TSRFO_CONSIGNEE>0001</TSRFO_CONSIGNEE>
            </E1EDK33>
            <E1EDK33 SEGMENT="1">
                <TSNUM>0002</TSNUM>
                <TSRFO>0002</TSRFO>
                <TSRFO_CONSIGNEE>0002</TSRFO_CONSIGNEE>
            </E1EDK33>
            <E1EDK33 SEGMENT="1">
                <TSNUM>0001</TSNUM>
                <TSRFO>0001</TSRFO>
                <TSRFO_CONSIGNEE>0003</TSRFO_CONSIGNEE>
            </E1EDK33>
            <E1ETD01 SEGMENT="1">
                <DGMDDAT>20220321</DGMDDAT>
            </E1ETD01>
        </E1EDT20>
    </IDOC>
</SHPMNT06>

I have tried to exclude E1EDK33 from the select <xsl:apply-templates select="*"/> like this: <xsl:apply-templates select="*/*[not(E1EDK33)]"/> and a lot of other permutations but I can't seem to get rid of the duplicated E1EDK33. Either it completely messes up my file or it duplicates it.


Solution

  • You could do

      <xsl:template match="E1EDT20">
        <xsl:copy>
          <xsl:apply-templates select="@*"/>
          <xsl:apply-templates select="E1EDK33[1]/preceding-sibling::*"/>
          <xsl:apply-templates select="E1EDK33">
            <xsl:sort select="TSRFO_CONSIGNEE" data-type="number" order="ascending"/>
          </xsl:apply-templates> 
          <xsl:apply-templates select="E1EDK33[last()]/following-sibling::*"/>
        </xsl:copy>
      </xsl:template>