XSLT 1.0中position()计数错误,如何为XML标签添加连续identifier属性
问题原因
你原有XSLT的错误来自两个核心逻辑问题:
- 模板匹配了所有节点类型(包含属性、文本、注释等),给非元素节点添加属性本身是无效操作,同时会导致计数规则混乱
position()的计数范围是当前apply-templates选中的节点集,你在父节点下选中了@*|node(),元素的属性、标签之间的空白换行文本节点都会被计入计数,最终得到的序号不符合预期
修复后的XSLT代码(纯XSLT 1.0标准语法,无外部依赖)
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" omit-xml-declaration="no" indent="yes"/> <!-- 处理非元素节点:直接原样复制 --> <xsl:template match="@*|text()|comment()|processing-instruction()"> <xsl:copy/> </xsl:template> <!-- 仅处理元素节点,添加连续序号的identifier属性 --> <xsl:template match="*"> <xsl:copy> <xsl:attribute name="identifier"> <!-- 按文档全局顺序统计所有元素的出现序号 --> <xsl:number level="any" count="*"/> </xsl:attribute> <!-- 复制原有属性 --> <xsl:apply-templates select="@*"/> <!-- 处理子节点 --> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
代码说明
- 拆分了节点匹配规则,仅给元素节点添加
identifier属性,其他节点原样保留,完全兼容你的原有XML结构 - 使用XSLT 1.0原生的
<xsl:number>实现全局元素序号计数,不需要依赖任何外部脚本,所有支持XSLT 1.0的现代浏览器都可以正常运行 - 输出结果和你给出的预期结果完全一致
内容的提问来源于stack exchange,提问作者Zen
相关产品推荐
相关产品推荐

