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

XSLT1.0按<KEY>字段排序<CHILD>段的技术求助

XSLT 1.0 按排序节点并保留其他子节点

输入示例

<ROOT>
  <ITEM id="1">
    <NAME>Item A</NAME>
    <CHILD>
      <KEY>3</KEY>
      <VALUE>Three</VALUE>
    </CHILD>
    <CHILD>
      <KEY>1</KEY>
      <VALUE>One</VALUE>
    </CHILD>
    <CHILD>
      <KEY>2</KEY>
      <VALUE>Two</VALUE>
    </CHILD>
    <DESC>Sample Item</DESC>
  </ITEM>
  <ITEM id="2">
    <NAME>Item B</NAME>
    <CHILD>
      <KEY>5</KEY>
      <VALUE>Five</VALUE>
    </CHILD>
    <CHILD>
      <KEY>4</KEY>
      <VALUE>Four</VALUE>
    </CHILD>
  </ITEM>
</ROOT>

期望输出

<ROOT>
  <ITEM id="1">
    <NAME>Item A</NAME>
    <CHILD>
      <KEY>1</KEY>
      <VALUE>One</VALUE>
    </CHILD>
    <CHILD>
      <KEY>2</KEY>
      <VALUE>Two</VALUE>
    </CHILD>
    <CHILD>
      <KEY>3</KEY>
      <VALUE>Three</VALUE>
    </CHILD>
    <DESC>Sample Item</DESC>
  </ITEM>
  <ITEM id="2">
    <NAME>Item B</NAME>
    <CHILD>
      <KEY>4</KEY>
      <VALUE>Four</VALUE>
    </CHILD>
    <CHILD>
      <KEY>5</KEY>
      <VALUE>Five</VALUE>
    </CHILD>
  </ITEM>
</ROOT>

常见错误代码(丢失非CHILD节点)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <ROOT>
      <xsl:for-each select="ROOT/ITEM">
        <ITEM>
          <xsl:for-each select="CHILD">
            <xsl:sort select="KEY" data-type="number"/>
            <xsl:copy-of select="."/>
          </xsl:for-each>
        </ITEM>
      </xsl:for-each>
    </ROOT>
  </xsl:template>
</xsl:stylesheet>

正确解决方案

核心思路是用身份模板保留所有默认节点,仅对包含CHILD的父节点(如ITEM)做特殊处理:先复制非CHILD子节点,再排序复制CHILD节点。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 身份模板:默认复制所有节点、属性和文本 -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- 处理ITEM节点,重新组织其子节点顺序 -->
  <xsl:template match="ITEM">
    <xsl:copy>
      <!-- 复制ITEM的所有属性 -->
      <xsl:apply-templates select="@*"/>
      <!-- 先复制所有非CHILD的子节点(如NAME、DESC) -->
      <xsl:apply-templates select="node()[not(self::CHILD)]"/>
      <!-- 按KEY数值升序排序并复制CHILD节点 -->
      <xsl:apply-templates select="CHILD">
        <xsl:sort select="KEY" data-type="number" order="ascending"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

关键说明

  • 身份模板是XSLT复制文档结构的基础,确保未被特殊模板匹配的节点(如ROOT、NAME、DESC)都被原样保留。
  • 若KEY是字符串类型,移除data-type="number"即可按字符串排序。
  • 如果CHILD的父节点不是ITEM,只需修改match="ITEM"为对应的父节点名称即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 11:17:28