You need to enable JavaScript to run this app. XSLT如何将同id后续定义的pardef属性应用到对应par完成DXL转HTML
优惠活动
大模型
产品
解决方案
定价
更多

XSLT如何将同id后续定义的pardef属性应用到对应par完成DXL转HTML

DXL转HTML跨节点段落关联实现方案

核心思路

XSLT不需要靠可变变量、手动维护数组来解决跨位置的id匹配问题,原生的xsl:key全局索引机制天生适配这类「节点位置不固定、靠id属性关联」的场景,不管pardef和par谁在前谁在后,只要id值匹配,就能随时查到对应的段落定义属性。

具体实现步骤

1. 全局建立段落定义索引

在XSLT的顶层(和原有<xsl:template>平级的位置)添加索引定义,把所有pardef节点按id属性建立快速查找映射:

<xsl:key name="pardef-by-id" match="dxl:pardef" use="@id" />

索引会在整个文档树加载完成后自动构建,不受节点物理位置的影响。

2. 用相邻分组逻辑批量处理连续段落

原来逐节点循环渲染的逻辑,会把连续同属一个列表的par拆成零散标签,无法拼成结构完整的<ul>/<ol>容器。这里用XSLT 3.0原生的for-each-group相邻分组能力,把连续、同类型属性的段落归为一组整体渲染。
替换原有richtext节点的处理模板:

<xsl:template match="dxl:item/dxl:richtext">
    <div>
        <!-- 按相邻连续的段落属性分组 -->
        <xsl:for-each-group select="*" group-adjacent="
            (: 判断当前节点是不是带列表属性的par:是则按列表类型分组,否则按节点类型分组 :)
            if (
                self::dxl:par 
                and exists(key('pardef-by-id', @def)/@list)
            ) then key('pardef-by-id', @def)/@list
            else name()
        ">
            <xsl:choose>
                (: 无序列表组渲染 :)
                <xsl:when test="current-grouping-key() = 'bullet'">
                    <ul>
                        <xsl:apply-templates select="current-group()" mode="list-item" />
                    </ul>
                </xsl:when>
                (: 有序列表组渲染 :)
                <xsl:when test="current-grouping-key() = 'number'">
                    <ol>
                        <xsl:apply-templates select="current-group()" mode="list-item" />
                    </ol>
                </xsl:when>
                (: pardef节点是定义节点,不渲染到页面 :)
                <xsl:when test="current-grouping-key() = 'dxl:pardef'">
                </xsl:when>
                (: 普通非列表段落走原有渲染逻辑 :)
                <xsl:otherwise>
                    <xsl:apply-templates select="current-group()" mode="normal-par" />
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each-group>
    </div>
</xsl:template>

3. 补充分组对应的渲染模板

把原有处理段落、内联样式的逻辑,分别适配到两个模板模式下,不需要改动核心的字体、颜色、加粗这类已经实现好的样式逻辑:

<!-- 列表项模板:每个匹配的par渲染为<li>节点 -->
<xsl:template match="dxl:par" mode="list-item">
    <li>
        <xsl:for-each select="*">
            <xsl:call-template name="richtext.inline" />
        </xsl:for-each>
    </li>
</xsl:template>

<!-- 普通段落模板:保留原有换行渲染逻辑 -->
<xsl:template match="dxl:par" mode="normal-par">
    <xsl:for-each select="*">
        <xsl:call-template name="richtext.inline" />
    </xsl:for-each>
    <br />
</xsl:template>

适配说明

  • 该方案完全兼容你当前使用的XSLT 3.0版本,不需要额外升级运行环境。
  • 空的自闭合<par def='xx'/>节点会自动归入普通段落组,渲染为换行效果,和原有逻辑保持一致。
  • 后续如果需要支持嵌套列表,只需要在分组key的计算逻辑中,把pardef的缩进层级属性(如leftmargin、listindent)加入分组判断条件,即可自动生成对应嵌套层级的列表结构。

内容的提问来源于stack exchange,提问作者Call Me Audric

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.05 06:15:06