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
相关产品推荐
相关产品推荐

