XSL/XSLT中如何批量将pageTitle模板应用到多个title元素
问题根因
你当前编写的XSL模板仅直接匹配携带role属性的title节点本身,XSLT默认不会自动继承父节点的属性匹配规则,嵌套在title下的term、translation节点、以及独立存储的多语言term节点,都没有命中pageTitle对应的模板分支,因此无法自动套用样式,必须给每个节点单独加role属性才能触发匹配。
实现方案
核心思路是抽离公共样式逻辑+批量指定匹配范围+统一渲染内部内容,全程不需要给子节点重复添加role属性。
方案1:通用匹配规则(推荐,适配嵌套节点+独立term节点)
- 首先把pageTitle的FO样式抽成可复用的命名模板,避免重复编写样式代码:
<!-- 抽离pageTitle通用FO样式,所有需要套用该样式的节点统一调用此模板 --> <xsl:template name="build-pageTitle-block"> <fo:block font-size="30pt" color="#502a7d" font-family="AvenirNextLTProBold"> <xsl:apply-templates select="node()"/> </fo:block> </xsl:template>
- 批量配置所有需要套用pageTitle样式的节点匹配规则,覆盖三类场景:
- 带
role="pageTitle"的父title节点 - 父title为pageTitle时,内部嵌套的所有term、translation子节点(直接透传内容,不额外生成FO块避免样式错乱)
- 独立存储的多语言term节点(比如你提到的partB.title、partC.title,可自行扩展节点列表)
<!-- 匹配所有直接需要生成pageTitle块的目标节点 --> <xsl:template match="title[@role='pageTitle'] | term[@key='partB.title'] | term[@key='partC.title']"> <xsl:call-template name="build-pageTitle-block"/> </xsl:template> <!-- 匹配pageTitle块内部的嵌套子节点,仅透传文本/多语言内容,不触发其他模板逻辑 --> <xsl:template match="title[@role='pageTitle']//term | title[@role='pageTitle']//translation"> <xsl:apply-templates/> </xsl:template>
如果你的term节点是用
name属性而非key存储标识,把上述代码里的@key替换为@name即可。
方案2:专属mode渲染(适合模板逻辑复杂、怕匹配冲突的场景)
如果你的XSL工程里已经有大量term、translation的全局匹配规则,怕上述匹配优先级冲突,可以用专属mode隔离pageTitle域的渲染逻辑:
<!-- 统一匹配所有需要套用pageTitle样式的节点,内部用专属mode渲染内容 --> <xsl:template match="title[@role='pageTitle'] | term[@key='partB.title'] | term[@key='partC.title']"> <fo:block font-size="30pt" color="#502a7d" font-family="AvenirNextLTProBold"> <xsl:apply-templates select="node()" mode="pageTitle-inner"/> </fo:block> </xsl:template> <!-- pageTitle专属渲染mode下,所有元素节点只透传内部内容,不触发其他全局样式 --> <xsl:template match="*" mode="pageTitle-inner"> <xsl:apply-templates select="node()" mode="pageTitle-inner"/> </xsl:template>
避坑提示
- 不要为每个嵌套子节点单独生成
fo:block,否则会把一个完整标题拆成多个独立块,出现多余换行、间距异常的问题,所有子内容要放在同一个pageTitle对应的FO块内部 - 后续新增需要套用pageTitle样式的节点,只需要把节点路径加到匹配规则的
match属性里即可,不需要修改子节点结构、重复加role属性
内容的提问来源于stack exchange,提问作者user17710829
相关产品推荐
相关产品推荐

