如何合并XSLT样式表正确转换K4 XML的块引用、列表、标题与段落
XSLT样式表合并解决方案
核心思路是用身份转换模板作为底层基础,统一调度两份样式表的匹配逻辑,避免节点遗漏或顺序错乱,具体实现步骤如下:
第一步:添加全局身份转换模板
在合并后的XSLT根节点下首先添加以下模板,保证未被自定义模板匹配的节点、属性、文本内容都按原始顺序复制输出,从根源避免内容丢失:
<xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template>
第二步:合并两份样式表的匹配模板,设置优先级避免冲突
你可以直接把两份样式表的自定义模板复制到同一个XSLT文件中,给处理块级元素(blockquote、ol/ul、li)的模板设置更高优先级,避免和基础文本模板冲突:
- 基础文本元素(h1h6、p、加粗、斜体、超链接)的模板保留原有逻辑,统一给h1h6添加
class="imported"属性即可 - 块引用模板保留原有属性绑定逻辑,示例如下:
<xsl:template match="blockquote" priority="2"> <blockquote cite="{@blockquote-cite}"> <xsl:apply-templates/> </blockquote> </xsl:template>
- 列表处理模板保留原有分组逻辑,给生成的li添加
class="imported"属性,示例如下(针对相邻列表项分组生成外层ol/ul的逻辑):
<xsl:template match="*[starts-with(name(), 'list-item')]" priority="3"> <xsl:for-each-group select="." group-adjacent="if(@type='ordered') then 'ol' else 'ul'"> <xsl:element name="{current-grouping-key()}"> <xsl:apply-templates select="current-group()" mode="list-item"/> </xsl:element> </xsl:for-each-group> </xsl:template> <xsl:template match="*[starts-with(name(), 'list-item')]" mode="list-item"> <li class="imported"> <xsl:apply-templates/> </li> </xsl:template>
第三步:输出外层textobject节点
在根模板中指定输出外层包裹节点,按原始顺序应用所有模板即可:
<xsl:template match="/"> <textobject> <xsl:apply-templates select="/*/node()"/> </textobject> </xsl:template>
注意事项
- 所有自定义模板内部必须用
<xsl:apply-templates/>而非<xsl:value-of/>处理子节点,才能保证行内格式化元素(加粗、斜体、超链接)正常输出 - 如果两份样式表存在同名匹配模板,删除逻辑重复的部分,保留匹配粒度更细的版本即可
内容的提问来源于stack exchange,提问作者Noel Bügler
相关产品推荐
相关产品推荐

