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
相关产品推荐
相关产品推荐

