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

如何用XSL为DocBook目录不同层级设置差异化格式?修改autotoc.xsl遇阻

嘿,我之前折腾过DocBook目录的样式定制,刚好能给你支招!你说改autotoc.xsl没生效,大概率是没摸对模板优先级、没匹配对toc模式,或者直接修改原生文件后处理器没加载到改动后的版本——直接改原生文件也不是最佳实践,不如自己写个自定义样式表来覆盖,既安全又好维护。

下面分两种常见输出场景给你具体实现方案:

一、生成PDF(使用XSL-FO)

创建一个名为custom-toc.xsl的自定义样式表,导入DocBook的基础FO样式表,然后重写不同章节级别的toc模板:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fo="http://www.w3.org/1999/XSL/Format">

  <!-- 导入DocBook官方FO样式表,路径根据你的本地安装位置调整 -->
  <xsl:import href="docbook-xsl-ns/fo/docbook.xsl"/>

  <!-- 重写顶级章节(sect1)的目录条目:加粗+指定字体字号 -->
  <xsl:template match="sect1" mode="toc">
    <fo:list-item>
      <fo:list-item-label end-indent="label-end()">
        <fo:block>
          <xsl:number level="multiple" count="chapter|sect1" format="1. "/>
        </fo:block>
      </fo:list-item-label>
      <fo:list-item-body start-indent="body-start()">
        <fo:block font-family="Arial" font-size="12pt" font-weight="bold">
          <xsl:apply-templates select="." mode="toc-link"/>
        </fo:block>
        <!-- 递归处理子章节sect2 -->
        <xsl:apply-templates select="sect2" mode="toc"/>
      </fo:list-item-body>
    </fo:list-item>
  </xsl:template>

  <!-- 重写sect2的目录条目:不加粗+不同字体字号 -->
  <xsl:template match="sect2" mode="toc">
    <fo:list-item margin-left="15pt">
      <fo:list-item-label end-indent="label-end()">
        <fo:block>
          <xsl:number level="multiple" count="chapter|sect1|sect2" format="1.1 "/>
        </fo:block>
      </fo:list-item-label>
      <fo:list-item-body start-indent="body-start()">
        <fo:block font-family="Verdana" font-size="10pt" font-weight="normal">
          <xsl:apply-templates select="." mode="toc-link"/>
        </fo:block>
        <!-- 递归处理子章节sect3 -->
        <xsl:apply-templates select="sect3" mode="toc"/>
      </fo:list-item-body>
    </fo:list-item>
  </xsl:template>

  <!-- 重写sect3的目录条目:不加粗+另一组字体字号 -->
  <xsl:template match="sect3" mode="toc">
    <fo:list-item margin-left="30pt">
      <fo:list-item-label end-indent="label-end()">
        <fo:block>
          <xsl:number level="multiple" count="chapter|sect1|sect2|sect3" format="1.1.1 "/>
        </fo:block>
      </fo:list-item-label>
      <fo:list-item-body start-indent="body-start()">
        <fo:block font-family="Georgia" font-size="9pt" font-weight="normal">
          <xsl:apply-templates select="." mode="toc-link"/>
        </fo:block>
      </fo:list-item-body>
    </fo:list-item>
  </xsl:template>

</xsl:stylesheet>

二、生成HTML

如果是输出HTML,同样用自定义样式表覆盖模板,直接给链接加内联样式(或者后续用CSS统一管理):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- 导入DocBook官方HTML样式表,路径按需调整 -->
  <xsl:import href="docbook-xsl-ns/html/docbook.xsl"/>

  <!-- 顶级章节sect1的HTML目录条目 -->
  <xsl:template match="sect1" mode="toc">
    <li>
      <a href="{@id}.html" style="font-family: Arial; font-size: 12pt; font-weight: bold;">
        <xsl:number level="multiple" count="chapter|sect1" format="1. "/>
        <xsl:apply-templates select="title"/>
      </a>
      <xsl:if test="sect2">
        <ul>
          <xsl:apply-templates select="sect2" mode="toc"/>
        </ul>
      </xsl:if>
    </li>
  </xsl:template>

  <!-- sect2的HTML目录条目 -->
  <xsl:template match="sect2" mode="toc">
    <li>
      <a href="{@id}.html" style="font-family: Verdana; font-size: 10pt; font-weight: normal;">
        <xsl:number level="multiple" count="chapter|sect1|sect2" format="1.1 "/>
        <xsl:apply-templates select="title"/>
      </a>
      <xsl:if test="sect3">
        <ul>
          <xsl:apply-templates select="sect3" mode="toc"/>
        </ul>
      </xsl:if>
    </li>
  </xsl:template>

  <!-- sect3的HTML目录条目 -->
  <xsl:template match="sect3" mode="toc">
    <li>
      <a href="{@id}.html" style="font-family: Georgia; font-size: 9pt; font-weight: normal;">
        <xsl:number level="multiple" count="chapter|sect1|sect2|sect3" format="1.1.1 "/>
        <xsl:apply-templates select="title"/>
      </a>
    </li>
  </xsl:template>

</xsl:stylesheet>

关键注意事项

  1. 模板优先级:用<xsl:import>导入官方样式表,自定义模板会优先被调用,因为导入的模板优先级低于当前样式表的模板,这也是你之前改autotoc.xsl没生效的核心原因之一——原生模板优先级可能更高,或者你没匹配对mode="toc"。
  2. 字体可用性:如果是PDF输出,要确保你指定的字体(比如Arial、Verdana)已经安装在系统中,或者在样式表中通过fo:font-face指定字体文件路径,否则处理器会 fallback 到默认字体。
  3. 使用方式:用XSLT处理器(比如xsltproc)调用自定义样式表,而不是官方的:
# PDF输出示例(还需要后续用FOP等工具转PDF)
xsltproc custom-toc.xsl your-docbook.xml > output.fo
# HTML输出示例
xsltproc custom-toc.xsl your-docbook.xml > index.html

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:13:12