如何在XSLT和XSL-FO中实现主页码序列不受子序列干扰的多序列页码?
实现XSLT/XSL-FO多序列独立页码方案
要解决主序列页码不被子序列干扰的问题,核心是给主、子章节分配独立的页码序列,并在主序列续接时手动指定起始页码。以下是具体实现步骤:
1. 定义区分主/子章节的页面模板
在XSL-FO的<fo:layout-master-set>中,分别创建主章节和子章节的页面样式,以及对应的页面序列模板:
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <!-- 主章节页面模板 --> <fo:simple-page-master master-name="main-page" page-height="29.7cm" page-width="21cm" margin="2cm"> <fo:region-body/> <fo:region-after extent="1.5cm"> <fo:block text-align="center">主章节页码:<fo:page-number/></fo:block> </fo:region-after> </fo:simple-page-master> <!-- 子章节页面模板 --> <fo:simple-page-master master-name="sub-page" page-height="29.7cm" page-width="21cm" margin="2cm"> <fo:region-body/> <fo:region-after extent="1.5cm"> <fo:block text-align="center">子章节页码:<fo:page-number/></fo:block> </fo:region-after> </fo:simple-page-master> <!-- 主序列页面序列模板 --> <fo:page-sequence-master master-name="main-sequence"> <fo:repeatable-page-master-alternatives> <fo:conditional-page-master-reference master-reference="main-page"/> </fo:repeatable-page-master-alternatives> </fo:page-sequence-master> <!-- 子序列页面序列模板 --> <fo:page-sequence-master master-name="sub-sequence"> <fo:repeatable-page-master-alternatives> <fo:conditional-page-master-reference master-reference="sub-page"/> </fo:repeatable-page-master-alternatives> </fo:page-sequence-master> </fo:layout-master-set>
2. 处理主章节前半段并标记ID
给前半段主章节的<fo:page-sequence>设置唯一id,方便后续获取其最后页码:
<!-- 主章节前半部分 --> <fo:page-sequence master-reference="main-sequence" id="main-first-part"> <fo:flow flow-name="xsl-region-body"> <fo:block font-size="16pt" margin-bottom="1cm">主章节第1页内容</fo:block> <fo:block font-size="16pt" margin-bottom="1cm" page-break-before="always">主章节第2页内容</fo:block> <fo:block font-size="16pt" margin-bottom="1cm" page-break-before="always">主章节第3页内容</fo:block> </fo:flow> </fo:page-sequence>
3. 处理子章节,强制页码从1开始
每个子章节使用独立的<fo:page-sequence>,通过initial-page-number="1"重置页码,完全独立于主序列:
<!-- 第一个子章节 --> <fo:page-sequence master-reference="sub-sequence" initial-page-number="1"> <fo:flow flow-name="xsl-region-body"> <fo:block font-size="16pt" margin-bottom="1cm">子章节1第1页内容</fo:block> <fo:block font-size="16pt" margin-bottom="1cm" page-break-before="always">子章节1第2页内容</fo:block> </fo:flow> </fo:page-sequence> <!-- 第二个子章节 --> <fo:page-sequence master-reference="sub-sequence" initial-page-number="1"> <fo:flow flow-name="xsl-region-body"> <fo:block font-size="16pt" margin-bottom="1cm">子章节2第1页内容</fo:block> <fo:block font-size="16pt" margin-bottom="1cm" page-break-before="always">子章节2第2页内容</fo:block> </fo:flow> </fo:page-sequence>
4. 续接主章节,指定正确起始页码
使用<fo:page-number-citation>获取前半段主章节的最后页码,加1作为新主序列的起始页码:
<!-- 续接主章节,从主序列中断前的下一页开始 --> <fo:page-sequence master-reference="main-sequence" initial-page-number="{number(fo:page-number-citation(ref-id='main-first-part')) + 1}"> <fo:flow flow-name="xsl-region-body"> <fo:block font-size="16pt" margin-bottom="1cm">主章节续接第4页内容</fo:block> <fo:block font-size="16pt" margin-bottom="1cm" page-break-before="always">主章节续接第5页内容</fo:block> <fo:block font-size="16pt" margin-bottom="1cm" page-break-before="always">主章节续接第6页内容</fo:block> </fo:flow> </fo:page-sequence>
关键注意事项
- 确保每个主序列段的
<fo:page-sequence>都有唯一id,才能通过page-number-citation准确获取最后页码。 - 子序列必须显式设置
initial-page-number="1",避免继承主序列的页码计数。 - 部分XSL-FO处理器对
page-number-citation的支持可能有差异,测试时需确认处理器能正确解析ref-id对应的页码。
内容的提问来源于stack exchange,提问作者JablJak
相关产品推荐
相关产品推荐

