如何在DITA Open Toolkit+AntennaHouse PDF生成中获取并使用章节号?
XSL-FO Marker获取章节编号用于逻辑判断的问题解答
我是样式表开发新手,目前主要靠试错法开发。现在我想获取章节编号(样式表中已有相关模板),用来在when语句里使用,但尝试了多种方法都没成功,应该是对marker的工作机制和正确用法理解有误,恳请帮忙解答,或者提供靠谱的参考内容。
现有相关模板代码如下:
<xsl:template match="*" mode="randomName"> <fo:marker marker-class-name="current-chapter-number"> ... ... </fo:marker> </xsl:template>
<xsl:template name="randomName2"> <xsl:param name="flow-part" select="'body'"/> <xsl:variable name="nr"> <fo:retrieve-marker retrieve-class-name="current-chapter-number"/> </xsl:variable--><!-- 这里有语法错误,应改为</xsl:variable> --> <fo:static-content flow-name="odd-{$flow-part}-tabs"> <fo:block-container> <fo:block> <xsl:value-of select="$nr"/> </fo:block> </fo:block-container> </fo:static-content> </xsl:template>
核心问题分析
你现在的误区是混淆了XSLT逻辑层和FO格式层的边界:
fo:marker是FO格式层元素,只能在fo:flow的流内容(正文区域)里定义,用来标记当前页面的上下文信息;fo:retrieve-marker同样属于FO层,仅能在fo:static-content(页眉、页脚这类固定内容)里渲染输出,它没法被XSLT变量转换成纯文本值——你用<xsl:variable name="nr"><fo:retrieve-marker.../></xsl:variable>得到的是包含FO元素的节点集,不是字符串,自然没法在xsl:when的test条件里使用。
另外,第二个模板里的<xsl:variable-->是明显语法错误,会导致变量$nr定义失效。
解决方案
方案1:直接从XML源获取章节编号(推荐)
不要依赖marker做XSLT逻辑判断,直接从XML源文档提取章节编号,或者在生成marker的同时把编号存入XSLT变量:
<xsl:template match="*" mode="randomName"> <!-- 从XML节点取章节编号,比如对应节点的@number属性,或自动编号逻辑 --> <xsl:variable name="chapter-num" select="@number" /> <!-- 同时生成marker供静态内容使用 --> <fo:marker marker-class-name="current-chapter-number"> <xsl:value-of select="$chapter-num"/> </fo:marker> <!-- 后续在需要的地方直接用$chapter-num做when判断,比如: <xsl:when test="$chapter-num = '2'">...</xsl:when> --> </xsl:template>
方案2:若必须基于FO动态生成的编号
如果章节编号是FO生成阶段动态计算的(比如自动编号序列),要在流内容生成环节就完成逻辑判断,而非等到静态内容阶段用retrieve-marker:
- 在生成章节标题的模板里,先判断编号再决定输出格式;
- marker仅用于页眉页脚的显示,逻辑判断提前到流内容处理阶段。
关键知识点参考
- Marker核心规则:
fo:marker必须放在fo:flow内的元素中,fo:retrieve-marker只能在fo:static-content中使用,获取的是当前页面流中最近的同类型marker内容; - XSLT变量仅能存储XML节点、字符串、数字等数据,无法直接将FO元素转换为可用于逻辑判断的纯值,逻辑判断必须基于XML源或XSLT处理过程中生成的变量。
内容的提问来源于stack exchange,提问作者Davide
相关产品推荐
相关产品推荐

