You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>

原理说明

  1. XSLT位置判断:position()函数会返回当前节点在处理序列中的位置,不管子元素的名称是什么(item-abc、item-def等),只要是文档顺序里的第一个,就会触发initial-page-number的设置。
  2. XSL-FO行为:fo:page-sequence的initial-page-number属性默认值是auto,会自动延续上一个page-sequence的最后页码加1。只有第一个序列设置了指定页码,后续序列自然衔接,完全符合需求。

内容的提问来源于stack exchange,提问作者alhimik45

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:35:23