XSLT转换XML为HTML时被段落打断的ol列表如何连续编号
问题原因
你的代码有三个核心问题:
- 全局变量
$start的计算上下文是文档根节点,不是当前正在处理的<list>元素,<xsl:number>在根节点上下文下无法定位到当前列表的位置,因此返回空值,这就是start属性为空的直接原因。 - 全局变量仅会在样式表加载时计算一次,得到的是固定值,就算计算逻辑正确,也不可能为不同位置的
<list>返回各自对应的起始序号。 - 原计数逻辑存在偏差:
count="list"统计的是<list>标签本身的序号,不是所有列表项的累计数量,就算上下文正确,算出来的值也不是列表需要的起始编号。
可行方案
根据你的XSLT版本和使用场景选一种即可:
方案1:通过start属性实现(兼容所有XSLT版本)
不要用全局变量存序号,直接在匹配<list>的模板内计算当前列表的起始编号。假设你的列表项标签为<item>(如果是其他标签名替换对应位置即可),代码如下:
<xsl:template match="list"> <ol start="{count(preceding::list/item) + 1}"> <xsl:apply-templates/> </ol> </xsl:template>
逻辑很简单:统计当前列表之前文档内所有已经出现过的列表项总数,加1就是当前列表第一个项的起始序号,后续项会由浏览器自动按序递增。
方案2:硬编码每个列表项的序号(兼容性最好,推荐)
如果需要兼容老旧浏览器、或者存在列表嵌套场景,可以直接给每个<li>标签设置value属性指定全局序号,完全不依赖浏览器的默认计数逻辑:
<!-- 列表匹配模板,不需要额外设置start属性 --> <xsl:template match="list"> <ol> <xsl:apply-templates/> </ol> </xsl:template> <!-- 列表项匹配模板,直接计算全局序号 --> <xsl:template match="list/item"> <li value="{count(preceding::list/item) + 1}"> <xsl:apply-templates/> </li> </xsl:template>
如果是XSLT 2.0及以上版本,也可以用<xsl:number>实现更简洁的计数,避免XPath轴遍历的性能问题:
<xsl:template match="list/item"> <li> <xsl:attribute name="value"> <xsl:number level="any" from="body" count="list/item"/> </xsl:attribute> <xsl:apply-templates/> </li> </xsl:template>
内容的提问来源于stack exchange,提问作者TMiles
相关产品推荐
相关产品推荐

