DocBook 是一套基于 XML 的文档标记标准,它描述的是文档的逻辑结构,而不是最终呈现的版式。一个 DocBook 源文件本质上是一个纯文本 XML 文档,根元素通常是 <book> 或 <article>,内部使用 <chapter>、<para>、<itemizedlist> 等语义元素组织内容。编写者只需要关心这里是一个章节、一个段落、一个列表,具体生成何种字体、行距和分页则交给样式表处理。这种内容与表现分离的思路,使 DocBook 特别适合需要多格式交付和长期维护的技术出版物。

DocBook 的历史可以追溯到 1991 年,最初由 HaL Computer Systems 和 O'Reilly 合作开发,用来统一 UNIX 系统文档的编写格式。后来项目移交给 Davenport Group,又在 1998 年交由 OASIS 组织维护。DocBook 4.x 主要基于 DTD 定义,DocBook 5 则转向以 Relax NG 作为主模式语言,同时兼容 DTD 和 W3C XML Schema。这种演变让 DocBook 的校验能力更强,也更适合模块化扩展。
DocBook 的核心结构:面向书籍的语义元素
理解 DocBook 的关键,是区分语义元素和排版指令。比如 <chapter> 表示章,<sect1> 表示一级小节,<para> 表示段落,<programlisting> 表示需要保留空格和换行的代码或命令。DocBook 5 推荐使用 <section> 配合嵌套层级,取代旧版本中固定的 <sect1> 到 <sect5>,这让文档结构更灵活。一个典型的技术手册通常会包含 <book>、<chapter>、<para>、<itemizedlist>、<table>、<figure> 等元素。
下面是一个最小化的 DocBook 5 文档,它展示了一本书的根节点和基本层级。注意所有 XML 标签都需要正确闭合,而且 DocBook 5 要求使用命名空间 http://docbook.org/ns/docbook。
<book xmlns="http://docbook.org/ns/docbook" version="5.0">
<info>
<title>示例手册</title>
<author><personname>张三</personname></author>
</info>
<chapter>
<title>快速开始</title>
<para>这是第一段正文,用于说明环境准备步骤。</para>
<programlisting language="python">print("hello")</programlisting>
</chapter>
</book>
这段代码不会直接指定标题用什么字号、代码块用什么背景色,它只声明文档中有一个章、一个段落和一个程序清单。接下来就可以使用 DocBook XSL 样式表把同一个文件转换成 HTML、PDF 或 EPUB。语义化带来的好处是,当团队需要统一调整所有代码块的样式时,只需修改样式表参数,不需要逐篇手工排版。
DocBook 的元素库非常庞大,官方规范包含数百个元素。除了基础结构,它还支持 <index> 索引、<glossary> 术语表、<bibliography> 参考文献、<footnote> 脚注、<xref> 交叉引用等高级构件。对于软件文档,<funcsynopsis> 可以描述函数原型,<classsynopsis> 可以描述类结构。这种面向技术写作的丰富语义,是普通标记语言难以直接提供的。
使用 Relax NG 模式进行文档校验
DocBook 5 的主要模式语言是 Relax NG,这是一种基于 XML 的模式语言,比 DTD 更强大且更易于模块化。DocBook 的官方模式被拆分为多个 .rng 文件,分别定义通用属性、表格、列表、元信息等部分。开发者可以按需组合这些模块,也可以自定义一个精简版或扩展版模式。例如,某个项目如果不需要出版级的索引功能,可以在自定义模式中移除 index 模块,从而在编辑阶段就排除相关元素。
校验工具可以使用 jing 或 xmllint。jing 是一个专门的 Relax NG 校验器,执行下面的命令即可检查 manual.dbk 是否符合 DocBook 5 规范:
jing /usr/share/xml/docbook/schema/rng/5.0/docbook.rng manual.dbk
如果文档中存在未知元素或者属性名写错,工具会给出具体行号和错误原因。对于大型文档工程,建议把校验步骤加入持续集成流程。每次提交时自动运行校验,可以避免将结构错误带入后续转换环节。这与直接写 Markdown 相比,多了类型安全层面的保障,但也让初期配置显得更复杂。
DocBook 同样提供 DTD 版本,一些老旧的 SGML 处理工具仍然依赖 DTD。不过从 DocBook 5 开始,官方明确以 Relax NG 为主,DTD 和 W3C XML Schema 仅作为兼容产物。新项目若从零开始,直接使用 Relax NG 模式通常更合适,因为它的错误提示更清晰,而且支持命名空间和更灵活的内容模型。
XSLT 发布链:从单一源文档生成多格式输出
DocBook 自身不负责渲染,输出格式由 XSLT 样式表负责。官方提供的 DocBook XSL 样式表支持 HTML、XHTML、HTML Help、EPUB、XSL-FO 等多种目标。一个常见的命令行处理流程是使用 xsltproc 调用样式表:
xsltproc --output manual.html \ /usr/share/xml/docbook/stylesheet/docbook-xsl/html/chunk.xsl \ manual.dbk
这条命令中的反斜杠表示 shell 的续行,实际执行时会将三个部分合并为一条命令。chunk.xsl 会把文档拆分为多个 HTML 文件,每个 <chapter> 或 <section> 生成独立页面,并自动创建目录和上下页导航。如果只想生成单个 HTML 文件,可以换用 docbook.xsl。生成 PDF 通常需要先生成 XSL-FO,再由 Apache FOP 或 Antenna House Formatter 将 FO 对象转换为 PDF。这种方式的好处是同一份 DocBook 源文件可以同时交付网页版、打印版和电子书版。
实际项目中很少直接使用官方样式表而不做调整。DocBook XSL 提供了大量参数,例如 chapter.autolabel 控制章节编号、section.autolabel 控制小节编号、generate.index 控制是否生成索引。团队可以编写一个自定义样式层,只覆盖需要修改的模板,不必完全复制官方样式。这样既能复用官方逻辑,又能保持局部定制的可维护性。
需要注意的是,XSLT 转换是一个独立的 XML 处理步骤,与 DocBook 模式校验分离。文档可以先通过 jing 校验结构,再用 xsltproc 转换输出。两者的组合构成了 DocBook 的核心工具链:校验保证输入正确,转换负责结果生成。对复杂排版需求,还可以在转换前使用 XInclude 组合多个源文件,或用 XSLT 扩展函数实现动态内容。
DocBook 与 DITA、Markdown 的适用边界
提到结构化技术文档,另一个常见标准是 DITA。DITA 更强调主题化写作和内容重用,它的最小发布单元是 topic,可以按需组合成不同交付物。DocBook 则更接近传统书籍模型,以 book 或 article 为整体,章节层级连续。对于一套需要拆分到细粒度并在多个产品间复用的帮助系统,DITA 的映射和条件处理可能更顺手;对于一本结构完整、需要出版级别的技术书籍或毕业论文,DocBook 的语义模型和出版链更成熟。
Markdown 的流行确实解决了很多轻量场景下的写作问题,但它没有统一的语义标准,不同工具对表格、脚注、交叉引用的实现差异很大。Markdown 适合博客、README 和快速笔记,一旦文档规模变大,目录维护、多格式导出和团队协作就会遇到瓶颈。DocBook 通过严格的 XML 结构和成熟的 XSLT 工具链,为长文档提供了确定性更高的输出。代价则是学习曲线较陡,作者需要理解元素语义、模式校验和转换参数。
选择 DocBook 通常不是因为它简单,而是因为文档工程需要可靠性。如果团队已经具备 XML 处理经验,或者需要将文档纳入版本控制、自动化构建和审查流程,DocBook 可以显著减少后期排版返工。如果只是写几页内部说明,继续使用轻量标记语言可能更高效。理解这些边界,比单纯掌握 DocBook 语法更能帮助团队做出合适的技术决策。
DocBook XML 标准的核心价值,在于用规范化的结构描述替代自由格式的排版约定。它不会让写作像聊天一样随意,却能在文档规模扩大后保持可维护性和多目标发布能力。无论是软件手册、学术论文还是企业知识库,只要涉及长期维护和稳定输出,DocBook 仍然是一个值得投入学习的选项。