You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用xsl:sort排序时如何保留未排序元素的问题

问题:XSLT排序后丢失loops节点下的非loop元素

示例输入XML

<ns3:ASC858_004010 xmlns:ns3="http://sap.com">
<root>
    <name1/>
    <name2/>
    <loops>
        <name3/>
        <loop mode="2">
            <counter>2</counter>
        </loop>
        <loop mode="1">
            <counter>1</counter>
        </loop>
        <name4/>
    </loops>
    <name5/>
</root>
</ns3:ASC858_004010>

原XSLT代码

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="loops">
    <xsl:copy>
        <xsl:apply-templates select="loop">
            <xsl:sort select="counter"/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

当前输出结果

<ns3:ASC858_004010 xmlns:ns3="http://sap.com">
<root>
    <name1/>
    <name2/>
    <loops>
        <loop mode="1">
            <counter>1</counter>
        </loop>
        <loop mode="2">
            <counter>2</counter>
        </loop>
    </loops>
    <name5/>
</root>
</ns3:ASC858_004010>

期望输出结果

<ns3:ASC858_004010 xmlns:ns3="http://sap.com">
<root>
    <name1/>
    <name2/>
    <loops>
        <name3/>
        <loop mode="1">
            <counter>1</counter>
        </loop>
        <loop mode="2">
            <counter>2</counter>
        </loop>
        <name4/>
    </loops>
    <name5/>
</root>
</ns3:ASC858_004010>

错误原因

你的loops模板里仅对loop元素应用了模板,完全忽略了loops节点下的其他子元素(比如name3、name4),导致这些元素没有被复制到输出中。

修正后的XSLT代码

如果需要保留所有非loop元素的原始位置(name3在loop前、name4在loop后),可以分三步处理:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="loops">
    <xsl:copy>
        <!-- 处理所有在loop之前的非loop节点 -->
        <xsl:apply-templates select="node()[not(self::loop) and following-sibling::loop]"/>
        <!-- 排序处理loop元素,指定data-type确保数字排序准确 -->
        <xsl:apply-templates select="loop">
            <xsl:sort select="counter" data-type="number"/>
        </xsl:apply-templates>
        <!-- 处理所有在loop之后的非loop节点 -->
        <xsl:apply-templates select="node()[not(self::loop) and preceding-sibling::loop]"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

如果不需要区分位置,只需要保留所有非loop元素,也可以简化为:

<xsl:template match="loops">
    <xsl:copy>
        <!-- 先处理所有非loop子元素 -->
        <xsl:apply-templates select="*[not(self::loop)]"/>
        <!-- 再排序处理loop元素 -->
        <xsl:apply-templates select="loop">
            <xsl:sort select="counter" data-type="number"/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>

修正后的输出结果

<ns3:ASC858_004010 xmlns:ns3="http://sap.com">
<root>
    <name1/>
    <name2/>
    <loops>
        <name3/>
        <loop mode="1">
            <counter>1</counter>
        </loop>
        <loop mode="2">
            <counter>2</counter>
        </loop>
        <name4/>
    </loops>
    <name5/>
</root>
</ns3:ASC858_004010>

内容的提问来源于stack exchange,提问作者badbee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 12:41:01