xml - 使用 XSLT 对 XML 记录进行排序
问题描述
我有以下结构,我只需要根据其中的字段 ECI13 对 ECI 节点进行排序。
<?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>
预期产出
<?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>
我使用下面的 XSL 代码进行排序。输出只给我 ECI 记录(排序),而不是完整的有效负载。
<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>
下面是带有上述 xsl 代码的输出(缺少其他节点)。任何帮助将不胜感激。
<?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>
谢谢!!SM
解决方案
一种方法是
<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
它假设 ECI 元素是相邻的兄弟姐妹。