简体   繁体   中英

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.

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>

To exclude E1EDK33 elements in your select statement, you could use the self axis like so: *[not(self::E1EDK33)]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM