0
votes

I have the below structure, I have to sort only the ECI nodes based on the field ECI13 in it.

<?xml version="1.0" encoding="UTF-8"?>
<ns1:MT_test1 xmlns:ns1="https://www.xxxx.com/Import">
    <PRE>
        <ID>PRE</ID>
        <PRE01>LOAD</PRE01>
    </PRE>
    <MFT>
        <ID>MFT</ID>
        <MFT01>10000000822020</MFT01>
    </MFT>
    <REF>
        <ID>REF</ID>
        <REF01>10000000822020</REF01>
        <REF02>001</REF02>
    </REF>
    <REF>
        <ID>REF</ID>
        <REF01>10000000822020</REF01>
        <REF02>002</REF02>
    </REF>
    <REF>
        <ID>REF</ID>
        <REF01>10000000822020</REF01>
        <REF02>003</REF02>
    </REF>
    <REF>
        <ID>REF</ID>
        <REF01>10000000822020</REF01>
        <REF02>004</REF02>
    </REF>
    <DTM>
        <ID>DTM</ID>
        <DTM01>10000000822020</DTM01>
    </DTM>  
    <EH1>
        <ID>EH1</ID>
        <EH101>10000000822020</EH101>
    </EH1>  
    <ECI>
        <ID>ECI</ID>
        <ECI01>10000000822020</ECI01>
        <ECI02>001</ECI02>
        <ECI13>INV4500000044</ECI13>
    </ECI>
    <ECI>
        <ID>ECI</ID>
        <ECI01>10000000822020</ECI01>
        <ECI02>002</ECI02>
        <ECI13>INV4500000043</ECI13>
    </ECI>
    <ECI>
        <ID>ECI</ID>
        <ECI01>10000000822020</ECI01>
        <ECI02>003</ECI02>
        <ECI13>INV4500000042</ECI13>
    </ECI>
    <END>
        <ID>END</ID>
        <END01/>
    </END>
</ns1:MT_test1>

Expected Output

<?xml version="1.0" encoding="UTF-8"?>
<ns1:MT_test1 xmlns:ns1="https://www.xxxx.com/Import">
    <PRE>
        <ID>PRE</ID>
        <PRE01>LOAD</PRE01>
    </PRE>
    <MFT>
        <ID>MFT</ID>
        <MFT01>10000000822020</MFT01>
    </MFT>
    <REF>
        <ID>REF</ID>
        <REF01>10000000822020</REF01>
        <REF02>001</REF02>
    </REF>
    <REF>
        <ID>REF</ID>
        <REF01>10000000822020</REF01>
        <REF02>002</REF02>
    </REF>
    <REF>
        <ID>REF</ID>
        <REF01>10000000822020</REF01>
        <REF02>003</REF02>
    </REF>
    <REF>
        <ID>REF</ID>
        <REF01>10000000822020</REF01>
        <REF02>004</REF02>
    </REF>
    <DTM>
        <ID>DTM</ID>
        <DTM01>10000000822020</DTM01>
    </DTM>
    <EH1>
        <ID>EH1</ID>
        <EH101>10000000822020</EH101>
    </EH1>
    <ECI>
        <ID>ECI</ID>
        <ECI01>10000000822020</ECI01>
        <ECI02>003</ECI02>
        <ECI13>INV4500000042</ECI13>
    </ECI>
    <ECI>
        <ID>ECI</ID>
        <ECI01>10000000822020</ECI01>
        <ECI02>002</ECI02>
        <ECI13>INV4500000043</ECI13>
    </ECI>
    <ECI>
        <ID>ECI</ID>
        <ECI01>10000000822020</ECI01>
        <ECI02>001</ECI02>
        <ECI13>INV4500000044</ECI13>
    </ECI>
    <END>
        <ID>END</ID>
        <END01/>
    </END>
</ns1:MT_test1>

I am using the below XSL code for the sorting. The output gives me only the ECI records (sorted) and not the complete payload.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="https://www.xxxx.com/Import">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="ns1:MT_test1">
        <xsl:copy>
            <xsl:apply-templates select="@*" />
            <xsl:apply-templates select="ECI">
                <xsl:sort select="ECI13" order="ascending"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Below is the output with the above xsl code (which are missing the other nodes). Any help would be highly appreciated.

<?xml version="1.0" encoding="UTF-8"?>
<ns1:MT_test1 xmlns:ns1="https://www.xxxx.com/Import">
    <ECI>
        <ID>ECI</ID>
        <ECI01>10000000822020</ECI01>
        <ECI02>003</ECI02>
        <ECI13>INV4500000042</ECI13>
    </ECI>
    <ECI>
        <ID>ECI</ID>
        <ECI01>10000000822020</ECI01>
        <ECI02>002</ECI02>
        <ECI13>INV4500000043</ECI13>
    </ECI>
    <ECI>
        <ID>ECI</ID>
        <ECI01>10000000822020</ECI01>
        <ECI02>001</ECI02>
        <ECI13>INV4500000044</ECI13>
    </ECI>
</ns1:MT_test1>

Thanks!! SM

1
Will the ECI elements always be adjacent siblings with other elements only being positioned before or after them? Or can they be intermixed with other elements? Are the elements before or after known when writing the stylesheet?Martin Honnen

1 Answers

0
votes

One approach would be

  <xsl:template match="/*">
      <xsl:copy>
          <xsl:apply-templates select="@*"/>
          <xsl:for-each-group select="*" group-adjacent="boolean(self::ECI)">
              <xsl:apply-templates select="current-group()">
                  <xsl:sort select="if (current-grouping-key()) then ECI13 else position()"/>
              </xsl:apply-templates>
          </xsl:for-each-group>
      </xsl:copy>
  </xsl:template>

https://xsltfiddle.liberty-development.net/jxDiMCg

It assumes the ECI elemeents are adjacent siblings.