XSL-FO:如何为含不定序子元素的文档设置初始页码?
解决任意顺序子元素的第一个page-sequence初始页码设置问题
这个问题其实很常见,核心思路就是在XSLT层面精准识别root下第一个被处理的子元素,只给它对应的fo:page-sequence添加initial-page-number属性并传入指定的初始页码;后续子元素生成的page-sequence则不设置该属性(或设为默认的auto),让页码自动延续上一个序列的末尾。
具体实现方案
假设你的XSLT接收的初始页码参数名为$initial-page-number,可以这样写模板:
方法1:用xsl:apply-templates配合位置判断
<!-- 处理根节点root --> <xsl:template match="root"> <fo:root> <!-- 先定义页面布局模板,根据你的需求调整 --> <fo:layout-master-set> <fo:simple-page-master master-name="default-page" page-height="29.7cm" page-width="21cm" margin-top="2cm" margin-bottom="2cm" margin-left="2.5cm" margin-right="2.5cm"> <fo:region-body/> </fo:simple-page-master> </fo:layout-master-set> <!-- 处理root下的所有子元素,传递是否为第一个的参数 --> <xsl:apply-templates select="*"> <xsl:with-param name="is-first-node" select="position() = 1"/> </xsl:apply-templates> </fo:root> </xsl:template> <!-- 处理root下的任意子元素(item-abc、item-def等) --> <xsl:template match="root/*"> <xsl:param name="is-first-node"/> <fo:page-sequence master-reference="default-page"> <!-- 仅给第一个子元素对应的page-sequence设置初始页码 --> <xsl:if test="$is-first-node"> <xsl:attribute name="initial-page-number"> <xsl:value-of select="$initial-page-number"/> </xsl:attribute> </xsl:if> <!-- 子元素的内容渲染逻辑 --> <fo:flow flow-name="xsl-region-body"> <xsl:apply-templates/> </fo:flow> </fo:page-sequence> </xsl:template>
方法2:用xsl:for-each直接遍历子元素
如果习惯用循环遍历,也可以这样写:
<xsl:template match="root"> <fo:root> <fo:layout-master-set> <!-- 同样先定义页面模板 --> <fo:simple-page-master master-name="default-page" page-height="29.7cm" page-width="21cm"> <fo:region-body margin="2cm"/> </fo:simple-page-master> </fo:layout-master-set> <!-- 遍历root下所有子元素 --> <xsl:for-each select="*"> <fo:page-sequence master-reference="default-page"> <!-- 利用position()判断是否是第一个元素 --> <xsl:if test="position() = 1"> <xsl:attribute name="initial-page-number" select="$initial-page-number"/> </xsl:if> <fo:flow flow-name="xsl-region-body"> <xsl:apply-templates select="."/> </fo:flow> </fo:page-sequence> </xsl:for-each> </fo:root> </xsl:template>
原理说明
- XSLT位置判断:
position()函数会返回当前节点在处理序列中的位置,不管子元素的名称是什么(item-abc、item-def等),只要是文档顺序里的第一个,就会触发initial-page-number的设置。 - XSL-FO行为:
fo:page-sequence的initial-page-number属性默认值是auto,会自动延续上一个page-sequence的最后页码加1。只有第一个序列设置了指定页码,后续序列自然衔接,完全符合需求。
内容的提问来源于stack exchange,提问作者alhimik45
相关产品推荐
相关产品推荐

