使用匹配指定选择器的XSLT排序XML并保持原有结构不变
正确XSLT 1.0实现代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" encoding="utf-8" indent="yes" /> <!-- 身份转换模板:默认递归复制所有节点、属性、文本,保证其余内容完全不变 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 仅重写mpcconfiguration节点的处理逻辑,实现lineitem排序 --> <xsl:template match="mpcconfiguration"> <xsl:copy> <!-- 先复制根节点的所有属性 --> <xsl:apply-templates select="@*"/> <!-- 选中所有lineitem子节点,按要求规则排序 --> <xsl:apply-templates select="lineitem"> <xsl:sort select="category[@id='Mstr_Information']/option[@id='Mstr_Information']/property[@id='Mstr_ModelSortOrder']" data-type="number" order="ascending"/> </xsl:apply-templates> </xsl:copy> </xsl:template> </xsl:stylesheet>
如果不需要输出缩进,把xsl:output的indent属性改为no即可和你原配置的输出格式一致。
代码说明
- 以身份转换模板为基础规则,除了
mpcconfiguration节点的处理逻辑被重写外,其余所有XML内容都会被原样复制,完全满足"仅调整lineitem顺序、其余内容不变"的要求。 - 排序逻辑严格匹配需求:仅取每个
lineitem下,父节点为id="Mstr_Information"的option、祖父节点为id="Mstr_Information"的category的Mstr_ModelSortOrder属性节点值作为排序依据,data-type="number"确保按数值升序排列,不会出现字符串排序的错误。 - 所有不符合排序路径要求的
property节点(值为555、777、999的节点)都会被原样保留在原位置,不会被修改。
原代码问题说明
- 优先级冲突:你写的根节点匹配模板中直接用了
xsl:copy-of复制所有内容,该规则优先级更高,会直接输出原XML,导致后续匹配mpcconfiguration的模板完全不会生效。 - 排序对象错误:
apply-templates选择的是property节点,而实际需要排序的是lineitem节点,property的节点值仅作为排序依据即可,不需要单独选中处理。
内容的提问来源于stack exchange,提问作者HerrimanCoder
相关产品推荐
相关产品推荐

