求助:使用XSLT 1.0按指定字段对XML的segment节点升序排序
解决方案:XSLT 1.0 排序含的节点
问题核心
你需要仅对包含<field>子节点的<segment>节点执行升序排序,其余节点和内容保持原有结构与顺序。之前的XSLT无效通常是因为未精准筛选目标节点,或排序逻辑未结合节点特征处理。
正确实现代码
<?xml version="1.0" encoding="UTF-8"?> <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> <!-- 匹配包含目标<segment>的父容器(可根据实际XML修改容器节点名,比如改成具体的<root>) --> <xsl:template match="*[segment[field]]"> <xsl:copy> <xsl:apply-templates select="@*"/> <!-- 先输出不含<field>的<segment>,保留原有顺序 --> <xsl:apply-templates select="segment[not(field)]"/> <!-- 对含<field>的<segment>按<field>文本升序排序后输出 --> <xsl:apply-templates select="segment[field]"> <xsl:sort select="field" data-type="text" order="ascending"/> </xsl:apply-templates> <!-- 输出容器内的非segment节点,保留原有位置 --> <xsl:apply-templates select="node()[not(self::segment)]"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
关键逻辑说明
- 身份转换模板:确保所有未被特殊匹配的内容原样复制,保证非目标节点不受影响。
- 目标容器匹配:精准定位包含需排序
<segment>的父节点,避免全局干扰。 - 分批次处理:
- 先输出不含
<field>的<segment>,维持原有顺序。 - 对含
<field>的<segment>按指定规则排序后输出。 - 最后输出容器内的其他非segment节点,不打乱原有结构。
- 先输出不含
灵活调整
如果排序依据是<field>的属性(比如@id),只需将<xsl:sort>的select值改为field/@id即可。
内容的提问来源于stack exchange,提问作者James Taylor
相关产品推荐
相关产品推荐

