You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XSLT编号需求:为相邻or-item实现对应位置的二级编号

解决同级<or-item>的二级编号问题

我明白你的痛点——没法调整XML结构,只能从同级元素里把<or-item>和对应的<item>关联起来生成正确的二级编号。原来的代码里统计所有<or-item>总数的方式肯定不对,咱们来修改一下:

XSLT 1.1 兼容版本(适配xsltproc)

这个版本用XPath计算当前<or-item>在对应<item>组内的位置,完全兼容你当前的运行环境:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fo="http://www.w3.org/1999/XSL/Format"
                version="1.1"
                xmlns:axf="http://www.antennahouse.com/names/XSL/Extensions"
                xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output encoding="UTF-8" method="html" indent="yes"/>

    <xsl:template match="list">
        <div>
            <xsl:apply-templates/>
        </div>
    </xsl:template>

    <xsl:template match="item">
        <div>
            <xsl:number count="item"/>
            <xsl:text> </xsl:text>
            <xsl:value-of select="."/>
        </div>
    </xsl:template>

    <xsl:template match="or-item">
        <div style="padding-left: 10px">
            <!-- 核心逻辑:找到和当前or-item同属一个前置item的所有同级or-item,计算当前位置 -->
            <xsl:number 
                value="count(preceding-sibling::or-item[preceding-sibling::item[1] = current()/preceding-sibling::item[1]]) + 1"
                format="a) "/>
            <xsl:value-of select="."/>
        </div>
    </xsl:template>
</xsl:stylesheet>

逻辑拆解

这段XPath的作用是:

  1. current()/preceding-sibling::item[1] → 获取当前<or-item>前面最近的那个<item>
  2. preceding-sibling::or-item[preceding-sibling::item[1] = ...] → 筛选出所有和当前<or-item>共享同一个最近<item>的前置<or-item>
  3. 统计这些元素的数量再加1,就是当前<or-item>在组内的序号,配合format="a) "生成a)、b)这样的二级编号格式。

XSLT 2.0 简化版本(如果支持的话)

如果你的环境可以兼容XSLT 2.0,用分组功能会更清晰,代码可读性更强:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fo="http://www.w3.org/1999/XSL/Format"
                version="2.0"
                xmlns:axf="http://www.antennahouse.com/names/XSL/Extensions"
                xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output encoding="UTF-8" method="html" indent="yes"/>

    <xsl:template match="list">
        <div>
            <!-- 按item分组,把item和后面连续的or-item归为一组 -->
            <xsl:for-each-group select="item | or-item" group-starting-with="item">
                <!-- 处理组内的第一个元素(就是item) -->
                <div>
                    <xsl:number count="item"/>
                    <xsl:text> </xsl:text>
                    <xsl:value-of select="current-group()[1]"/>
                </div>
                <!-- 处理组内剩下的or-item -->
                <xsl:apply-templates select="current-group()[position() > 1]"/>
            </xsl:for-each-group>
        </div>
    </xsl:template>

    <xsl:template match="or-item">
        <div style="padding-left: 10px">
            <!-- 直接用组内的position()作为二级编号 -->
            <xsl:number value="position()" format="a) "/>
            <xsl:value-of select="."/>
        </div>
    </xsl:template>
</xsl:stylesheet>

逻辑拆解

用group-starting-with="item"把<list>下的元素按“item开头,后面跟连续的or-item”分组,每组对应一个item和它的备选项。处理组内元素时,item用一级编号,后面的or-item直接用组内的位置生成二级编号,逻辑更直观。

测试你的XML输入,最终输出的HTML会是:

<div>
   <div>1 Test</div>
   <div style="padding-left: 10px">a) TestOr</div>
   <div style="padding-left: 10px">b) TestOrr</div>
   <div>2 Testtt</div>
   <div style="padding-left: 10px">a) TestOrrr</div>
   <div>3 Testttt</div>
</div>

内容的提问来源于stack exchange,提问作者Pascal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:11:29