XSLT结合RenderX生成PDF时为指定属性元素加样式并匹配原有模板问题
XSLT通用元素前置样式适配方案
问题根因
你当前的代码出现递归/匹配失效的核心原因是:xsl:copy创建的是输出树的节点副本,你给副本添加的ns:changed属性仅存在于输出节点中,后续xsl:apply-templates select="."选中的仍是源文档的原始节点,原始节点从未携带ns:changed="true"属性,所以会持续命中高优先级模板造成死循环。
最优解决方案(适配XSLT 2.0及以上版本,无需修改原有模板)
直接使用XSLT内置的xsl:next-match特性,无需额外添加属性标记,即可自动调用原有匹配模板:
<xsl:template match="node()[@ns:change='del']" mode="#all" priority="10"> <fo:inline text-decoration="line-through" color="#FF0000"> <!-- 自动调用当前mode下优先级更低的原有元素匹配模板 --> <xsl:next-match/> </fo:inline> </xsl:template>
方案说明
- 优先级设为10,保证高于所有普通业务模板的默认优先级(普通元素匹配模板默认优先级最高为0.5),不会出现匹配不到的问题
- 完全兼容现有所有mode的模板,无需对原有上百个模板做任何修改
- 不需要额外添加状态属性,从根源避免递归问题
XSLT 1.0兼容方案
如果你的环境仅支持XSLT 1.0,可通过传参标记处理状态避免递归:
<xsl:template match="node()[@ns:change='del']" mode="#all" priority="10"> <xsl:param name="is_del_processed" select="false()"/> <xsl:choose> <xsl:when test="$is_del_processed"> <!-- 调用原有模板逻辑,若原有模板在导入样式表中使用xsl:apply-imports,否则可直接写原有通用处理逻辑 --> <xsl:apply-imports/> </xsl:when> <xsl:otherwise> <fo:inline text-decoration="line-through" color="#FF0000"> <xsl:apply-templates select="." mode="#current"> <xsl:with-param name="is_del_processed" select="true()"/> </xsl:apply-templates> </fo:inline> </xsl:otherwise> </xsl:choose> </xsl:template>
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

