如何在XSLT中按name排序attribute节点并按checker排序constraint子节点
XSLT实现双重排序:attribute节点按name排序 + constraint节点按checker属性排序
需求说明
已实现<attribute>节点按name属性排序,现在需要同时让每个<attribute>下的<constraint>子节点按checker属性值(如MinOccurs、ColumnPrecision等)排序。
当前代码(仅实现attribute节点内部子节点按名称排序)
<xsl:template match="attribute"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:apply-templates select="node()"> <xsl:sort select="name()"/> </xsl:apply-templates> </xsl:copy> </xsl:template>
XML示例结构
<attributes> <attribute documentIdentifier="false" name="Attribute02"> <constraints> <constraint checker="MinOccurs"> <settings>1</settings> </constraint> <constraint checker="ColumnPrecision"> <settings>12</settings> </constraint> <constraint checker="ColumnScale"> <settings>0</settings> </constraint> </constraints> <visibility document="false" hitlist="false" search="false"/> </attribute> <attribute documentIdentifier="false" name="Attribute01"> <constraints> <constraint checker="ColumnPrecision"> <settings>12</settings> </constraint> <constraint checker="ColumnScale"> <settings>0</settings> </constraint> </constraints> </attribute> </attributes>
预期结果
<attributes> <attribute documentIdentifier="false" name="Attribute01"> <constraints> <constraint checker="ColumnPrecision"> <settings>12</settings> </constraint> <constraint checker="ColumnScale"> <settings>0</settings> </constraint> </constraints> </attribute> <attribute documentIdentifier="false" name="Attribute02"> <constraints> <constraint checker="ColumnPrecision"> <settings>12</settings> </constraint> <constraint checker="ColumnScale"> <settings>0</settings> </constraint> <constraint checker="MinOccurs"> <settings>1</settings> </constraint> </constraints> <visibility document="false" hitlist="false" search="false"/> </attribute> </attributes>
解决方案
要实现双重排序,需要分别处理<attributes>下的<attribute>节点排序,以及<constraints>下的<constraint>节点排序,同时保留XSLT的默认复制逻辑(identity模板)。
完整XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 基础identity模板:复制所有未被特殊匹配的节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 对attributes下的attribute节点按name属性排序 --> <xsl:template match="attributes"> <xsl:copy> <xsl:apply-templates select="attribute"> <xsl:sort select="@name" order="ascending"/> </xsl:apply-templates> </xsl:copy> </xsl:template> <!-- 对constraints下的constraint节点按checker属性排序 --> <xsl:template match="constraints"> <xsl:copy> <xsl:apply-templates select="constraint"> <xsl:sort select="@checker" order="ascending"/> </xsl:apply-templates> </xsl:copy> </xsl:template> </xsl:stylesheet>
代码说明
- Identity模板:作为基础,确保所有未被自定义模板匹配的节点(如
<visibility>、<settings>等)都被原样复制,避免丢失内容。 - attributes节点模板:专门匹配
<attributes>父节点,对其子<attribute>节点按@name属性升序排序,实现attribute节点的整体排序。 - constraints节点模板:专门匹配
<constraints>父节点,对其子<constraint>节点按@checker属性升序排序,实现每个attribute内部constraint的排序。
这样组合后,就能同时满足双重排序的需求,输出结果与预期一致。
内容的提问来源于stack exchange,提问作者RunningLion
相关产品推荐
相关产品推荐

