XML 是一种通过在文本标记内包裹数据中不同的分层部分来标识该数据集内的结构化内容的机制,这些标记能够标示它们在该分层结构内所界定的那些文本的角色。这些文本标记,又称标记、标签、或更恰当的说是元素,符合预先定义的结构。该结构特定于不同的数据类型,通常称为 Schema,过去被称为 DTD。Schema 用 XML 编写,而 DTD 有自已的语法。
标记语言及 XML 本身的理念源起于文档生成系统,在这些系统中,文本文件包含了处理指令或用来标识文档的不同部分的结构标识符。这些文本文件可随后由软件处理,而这些软件知道如何解释这些指令以及如何生成针对特定的输出设备格式化了的输出。标记语言在文档处理方面的演变增加了使用标记的抽象性。
早期的标记语言使用格式化指令,它指定了较低级别的细节设置,例如字体及字体大小的变化。它们很快发展成了更为普遍的、可标识逻辑和结构组成(比如突出显示的术语、段落、列表、标题等)的标记。
较现代的标记语言,例如 Standard Generalized Markup Language(SGML)和 XML,则使像书、章、节等这类更为抽象的结构标记更易于为大众理解和接受。SGML 新加入了 DTD 的概念,这就使得 SGML 工具能够验证对特定的一些标记元素集和上下文的遵从性,这些元素在上下文中可以出现在某一类文档的结构内。
显而易见,XML 将标记从文档的领域中解放了出来,将它的使用范围扩展到了任何类型的结构化数据,并相应增加了对格式良好的 内容的要求,即每个元素都必须同时具备开始和结束标签。尽管 XML 规范的最初版本从 SGML 中继承了 DTD,但之后的版本则引入了 Schema 的概念以定义 XML 数据的结构。Schema 与 DTD 基本相同,只不过 Schema 本身也是用 XML 编写的,并且提供了一个更为灵活的模型来定义有效元素、元素的数据类型及 XML 文档中这些元素能够在其中出现的上下文。
将文档的内容(文档包含的确切的文字和数据)与文档的表示(文档以特定的输出格式或在特定的输出设备中显示的方式)分离开来是现代标记语言,更明确地说是 SGML 和 XML 背后的关键理念。
尽管 XML 简化了针对特定的应用或行业的 DTD 和 Schema 设计,但它在文档方面的真正优势却在于有大量现成的标准的 DTD 和 Schema 可用于文档标记。其中为人熟知的当属 DocBook、Text Encoding Initiative (TEI)、XHTML 以及 Darwin Information Typing Architecture (DITA) 所采用的那些 Schema 与 DTD。本文将重点介绍 DocBook,它是最著名也是最广泛用于文档标记的一种 Schema 。
由于其重心就是将内容与表示相分离,所以 XML 本质上是一个 “写一次,读多次” 的机制,这使得在多个文档中重用信息或针对特定的输出格式或群体定制信息都变得很容易。本系列中的另一篇文章将会深入探讨这些主题。
在本文的上下文环境中,术语发布 指的是将文档从一个包含 DocBook 标记的文本文件转换成一个或多个以特定格式(例如 HTML、Adobe® 的 Portable Document Format (PDF)、PostScript、Microsoft® 的 Rich Text Format (RTF) 等)表示的输出文件。从 XML 文档生成 HTML 输出只需一步就可完成,而且仅用一个应用程序就能生成 HTML 输出。生成 PDF、PostScript 或 RTF 输出的过程只需再多加一个步骤:
- 解析所包含的全部文档或 DocBook 文档内的外部引用,并用一个 XSL 样式表来生成这个文档的 Formatting Object(FO)格式的版本。
- 对于 PDF、PostScript 或 RTF 输出,将 DocBook 文档的 FO 版本转换为相应格式的输出文件即可。
很多开源工具都可用来进行这些转换,但本文中,我只重点介绍我发现的能提供最有用和最灵活解决方案的三种工具。 表 1 介绍了这些工具。
表 1. 本文所涵盖的的开源转换工具
| 工具 | 描述 |
|---|---|
fop | 一个将 XML 输入转换为 PDF、PostScript、RTF 等输出格式的 Java™ 应用程序。要执行这个应用程序,系统必须安装 Java Virtual Machine (JVM)。 |
xmlto | 一个简单的 Bourne-Again shell 脚本和能从 XML 输入生成 HTML 输出的一组相关样式表。这个脚本还需要另外的一些开源实用工具,例如 GNU find 和 mktemp。 |
xsltproc | 一个编译了的应用程序,能够使用 XSL 样式表将 XML 输入转换为另一种 XML 输出格式。要实现这种转换,还需要安装 DocBook XSL 样式表。只要有了恰当的样式表,fop 就可以接受 DocBook XML 输入,倘若 DocBook 输入文件有问题,使用独立的一个 XML 到 FO 转换器,比如 xsltproc,可以简化调试过程。 |
下面的几个小节将会介绍如何下载并安装这些应用程序。随后的小节 给出了一个 shell 脚本,它将之前介绍的内容综合起来并提供了一些便捷的方式来指定输出格式、定制样式表等。
要获得 前一个小节中 提到的软件和样式表,请参见 参考资料。
注意:如果使用的是 Linux 系统,那么 xmlto 和 xsltproc 实用工具已经安装在系统上了,或至少可以在此 Linux 发布版的存储库或安装媒介中找到。此外,还需要安装一个 JVM 来运行 fop— GNU Compiler,因为 Java 并不提供 fop 所需的全部功能。
很多这样的包都会把软件安装在指定的位置以便系统的包管理软件能够监控并根据需要更新软件。但这一点并不适用于 XSL 样式表和 Apache Formatting Objects Processor(FOP),因为它们是作为包含有一个顶级目录和多个子目录的归档文件被下载的。
要统一文档解析和格式化环境,最好是将不具备硬连接(hard-wired)路径名的包安装在一个尚不存在的目录(例如 /home/doc)内。这样做能够提供一个独立的位置,可以在其中查找相关的文件、在需要的时候升级软件和收集所开发或收藏的其他工具和样式表。
要使 前面小节 中所讨论的包与后面小节内提供的统一脚本协同工作,必须以 UNIX 或 Linux 系统的根用户执行 清单 1 内的命令。
清单 1. 使
fop、xmlto 和 xsltproc 能够与统一脚本协同工作而执行的命令
mkdir /home/doc
mkdir /home/doc/bin
mkdir /home/doc/external
mkdir /home/doc/external/SAVE
mkdir /home/doc/XSL
|
在下载了针对 FOP 和 DocBook XSL 样式表的压缩(.zip)文件后,可以将它们放在 /home/doc/external 目录,转到该目录,并使用 清单 2 内的命令解压缩其中的内容。
清单 2. 解压缩 FOP 和 DocBook XSL 样式表所需的命令
cd /home/doc/external
unzip fop-0.95-bin.zip
unzip docbook-xsl-1.74.3.zip
chmod 755 fop-0.95/fop
|
要验证所有必需的包是否已经全部安装到系统,可以执行 清单 3 内的命令。
清单 3. 验证所需包是否安装完毕所需的命令
xmlto --version
xsltproc --version
java --version
|
如果 xmlto 和 xsltproc 应用程序以及 JVM 均已正确安装到系统并保存于执行路径,上述命令中的每一个都会返回有关该应用程序的版本信息。
将 DocBook 发布所需的所有软件都安装到系统上后,所需做的就是记住所有必需的选项并按正确的顺序加以执行。当然,也可以编写一个包装器脚本将所有这些综合起来并提供对发布过程的某些控制,类似 清单 4、清单 5 和 清单 6 所示。
此脚本基于所提供的参数生成 HTML、PDF 或 RTF 输出。在生成 PDF 或 RTF 输出时,它使用一个两步过程来生成 PDF 输出,先是执行 xsltproc 从 DocBook 输入生成 FO 文件,其中使用了 driverfile 变量内找到的 XSL 样式表来识别转换规则。之后,这个包装器脚本使用 fop 应用程序从该文件生成目标输出格式。其中的每一个步骤都会从文件 xsltproc.out 和 fop.out 内所使用的应用程序(xsltproc 和 fop)获取消息。此脚本使用这些中间文件来监视转换过程并在出现问题时获取潜在的调试信息。
清单 4 给出了此示例包装器脚本的开始部分,其中定义了一个使用消息,如果在没有参数或参数数量错误的情况下执行该脚本,就会显示这个消息。它还为此脚本设置了某些默认值,然后使用标准的 Bash
shell 的 getopt 函数解析这些命令行参数(清单 7 给出了这个使用消息的输出)。
清单 4. 包装器脚本的初始部分
#! /bin/bash
#
# Simple script to generate HTML output from a DocBook file using
# xmlto, or to generate PDF/RTF output by generating a fo file,
# and then using Apache's FOP to format that.
#
# wvh@vonhagen.org
#
function usage {
echo "Usage: $0 [OPTIONS] document-name"
echo " -D : produce draft mode document"
echo " -d : use specified xsl driver (requires name of XSL file) "
echo " -h : generate HTML output (requires output directory name)"
echo " -k : attempt PDF generation even if xsltproc errors were encountered"
echo " -n : suppress TOC"
echo " -r : produce RTF output rather than PDF"
exit 1
}
dir=`dirname $0`
XSLTPROC="xsltproc"
PATH=$dir/../external/fop-0.95:${PATH}
if [ $# == 0 ] ; then
usage
exit
fi
driverfile="$dir/../external/docbook-xsl-1.74.3/fo/docbook.xsl"
# driverfile="$dir/../XSL/generic-print-driver.xsl"
draft="no"
keepgoing="no"
RTFoutput="no"
HTMLoutput="no"
while getopts ":d:h:Dknr" opt
do
case $opt in
d )
driverfile=$OPTARG
echo "Using driver file: $driverfile"
if [ ! -f $driverfile ] ; then
echo " Driver file not found"
exit 1
fi
;;
D )
draft="yes"
echo "Producing Draft Mode Document"
;;
h )
HTMLdir=$OPTARG
HTMLoutput="yes"
echo "Producing HTML output to $HTMLdir instead of PDF"
if [ -d $HTMLdir ] ; then
echo " Output directory $HTMLdir already exists"
exit 1
fi
;;
k )
keepgoing="yes"
echo "Will not stop if errors are encountered"
;;
n )
notoc="--stringparam generate.toc ''"
echo "Suppressing TOC..."
;;
r )
RTFoutput="yes"
echo "Producing RTF output rather than PDF"
;;
\? )
usage
exit 1;;
esac
done
shift $(($OPTIND - 1))
if [ ! -f $1 ] ; then
echo " Input file $1 not found - exiting."
exit
fi
|
清单 5 所示的这部分脚本的作用是:在试图生成 HTML 输出时,使用 xmlto 应用程序生成 HTML;在试图生成 PDF 或 RTF 输出时,使用 xsltproc 应用程序从输入 XML 文件创建 FO 输出。XML 到 FO 的转换步骤的输出被写入到一个名为 xsltproc.out 的临时文件,如果 xsltproc 应用程序在输入文件内遇到任何错误,临时文件能够简化调试的过程。若在此文件中检测到任何错误,脚本就会在生成 FO 文件后退出。之后您可以查看这个 xsltproc.out 文件,它应该能够有助于您发现和解决问题。与 清单 4 类似,也可以指定
-k 命令行选项来强制脚本继续,即便在 xsltproc 处理中检测到错误也是如此。
清单 5. 从输入 XML 文件生成 FO 输出
doc_base=`basename $1 .xml`
echo "Processing base name: $doc_base"
if [ x$HTMLoutput != "xno" ] ; then
xmlto -o $HTMLdir html $1
exit
fi
echo " Generating FO file: $doc_base.fo"
$XSLTPROC --output $doc_base".fo" \
--stringparam draft.mode $draft \
--stringparam fop1.extensions 1 \
--xinclude \
$notoc \
$driverfile \
$1 1> xsltproc.out 2> xsltproc.out
probs=`grep -i error xsltproc.out | wc -l | sed -e 's; ;;g'`
if [ x$probs != "x0" ] ; then
echo ""
echo "PROBLEMS:"
echo ""
cat xsltproc.out
echo ""
if [ x$keepgoing = "xno" ] ; then
exit
fi
fi
echo " Fixing FO file references to system images..."
cat $doc_base".fo" | sed -e "s;\"url(\.\./external/;\"url($dir/\.\./external/;g" > $$
mv $$ $doc_base".fo"
|
清单 6 给出了此脚本的最后部分,其中,使用了 fop 应用程序从一个 FO 文件生成 PDF 或
RTF 输出。与从 XML 到 FO 的转换过程类似,从 FO 到 PDF/RTF
转换步骤的输出也被写入到一个名为 fop.out 的临时文件,当 fop 应用程序在 FO 文件中遇到错误时,这个文件能够简化调试过程。如果 PDF/RTF 生成失败,您可以检查这个 fop.out 文件,它应该能够帮助您发现和解决问题。与 清单 4 类似,也可以指定 -k 命令行选项来强制脚本继续,即便在 xsltproc 处理过程中检测到错误也是如此。
清单 6. 从 FO 文件生成 PDF 或 RTF 输出
if [ x$RTFoutput = "xno" ] ; then
echo " Generating PDF file: $doc_base"".pdf"
fop -fo $doc_base".fo" -pdf $doc_base".pdf" 1> fop.out 2> fop.out
else
echo " Generating RTF file: $doc_base"".rtf"
fop -fo $doc_base".fo" -rtf $doc_base".rtf" 1> fop.out 2> fop.out
fi
probs=`grep -i Exception fop.out | wc -l | sed -e 's; ;;g'`
if [ x$probs != "x0" ] ; then
echo ""
echo "EXCEPTION OCCURRED DURING PROCESSING:"
echo ""
cat fop.out
echo ""
fi
|
可以下载这个名为 xml-format.sh 的示例脚本(参见 下载 部分的 xml-format.zip)。要在系统上安装此脚本,下载这个 zip 文件并将 xml-format.sh 解压缩到 /home/doc/bin 目录。使用如下命令来确保此脚本是可执行的:
chmod 755 /home/doc/bin/xml-format.sh
|
最后,确保 /home/doc/bin 目录位于执行路径中,方法是编辑 ~/.bashrc 文件并在该文件的末尾添加如下这行代码,也可以在系统 shell 提示符中作为命令执行这行代码:
export PATH=/home/doc/bin:${PATH}
|
如果将此命令添加到 ~/.bashrc 文件,请在当前的登录会话中提供该文件的来源,以便所做的更改在当前 shell 中立即生效。为此,执行如下的命令:
source ~/.bashrc
|
在没有参数的情况下执行这个 xml-format.sh 脚本会显示有关脚本如何使用的总结信息,如 清单 7 所示。
清单 7. 在没有参数的情况下执行 xml-format.sh 脚本后的输出
Usage: xml-format.sh [OPTIONS] document-name
-D : produce draft mode document
-d : use specified xsl driver (requires name of XSL file)
-h : generate HTML output (requires output directory name)
-k : attempt PDF generation even if xsltproc errors were encountered
-n : suppress TOC
-r : produce RTF output rather than PDF
|
要生成 DocBook 文档的 PDF 版本,只需以该文档的名称执行此脚本,如下面的例子所示:
xml-format.sh sample-document.xml
|
要使用此脚本生成这个 DocBook 文档的 HTML 版本,必须使用 -h 选项并为 HTML 输出文件指定目标目录的名称。例如,要在 HTML-output 目录(相对于当前的工作目录)创建 DocBook 文档的 HTML 版本,可以执行如下命令:
xml-format.sh -h HTML-output sample-document.xml
|
默认情况下,本文提供的 xml-format.sh 脚本使用的是 DocBook XSL 包内提供的默认输出样式表。若要进行定制,需要创建您自己的样式表以便先加载默认的 DocBook XSL 样式表,然后提供想要覆盖的那些特定参数的定制值。定制层的一个例子可在 generic-print-driver.xsl 样式表内找到(参见 下载 部分获得 generic-print-driver.zip)。
要为 xml-format.sh 脚本使用不同的样式表,可使用 -d 选项来指定想要使用的样式表的完整或相对路径名,或者也可以修改 xml-format.sh 脚本内的 driverfile 变量的值。示例脚本中有一行代码允许您使用示例 generic-print-driver.xsl 脚本。只需注释掉 driverfile 变量之前的值并取消随后一行的注释,该行包含新的定义。
XML 的强大功能和灵活性、多组现有标准以及用于处理和转换 XML 文档的丰富工具让安装和配置您自己的一组工具来从 XML 文档生成各种格式的输出变得十分简单。虽然现在有很多商业工具可用来编辑和格式化 XML 文档,但是创建您自己的工具集实现此目的有助于您更好地理解此过程,而且成本更低。
| 描述 | 名字 | 大小 | 下载方法 |
|---|---|---|---|
| 示例 DocBook 格式化脚本 | xml-format.zip | 2KB | HTTP |
| DocBook 的示例 XSL 定制 | generic-print-driver.zip | 1KB | HTTP |
学习
- DocBook: The Definitive Guide:获得有关 SGML 和 XML 内的 DocBook 标记的全部信息。本书的全部内容可以在线获得,但是如果您想要用 DocBook 进行正式的发布,那么此书非常值得您去购买。
- DocBook XSL: The Complete Guide:阅读有关 DocBook 样式表和发布的权威信息。本书的全部内容可以在线获得,但是如果您想要用 DocBook 进行正式的发布,那么此书非常值得您去购买。
- What is XSL-FO?(G. Ken Holman,O'Reilly xml.com,2002 年 3 月):研读这个对 XSL Formatting Object 规范的优秀介绍。
- OASIS DocBook Technical Committee:获得有关 DocBook 标准现有和将来版本的信息。OASIS Web 站点提供了大量有关 XML 和其他开放标准的信息。
- OASIS 上与 DocBook 相关的邮件列表:加入对 DocBook 标记以及用来处理和格式化 DocBook 文档的应用程序的讨论。
- XML Schema 1.1,第 1 部分:XML Schema 1.1 简介(Neil Delima,Sandy Gao. Michael Glavassevich,Khaled Noaman; developerWorks;2008 年 12 月):获得有关定义和组织 XML Schema 的详细信息。
- DTD, XML Schema, and DSD:获得 DTD 和 schema 之间的一个很好的对比以及指向 An Introduction to XML and Web Technologies 的一个链接,这是一本名副其实的好书。
- IBM XML 认证:了解如何成为 IBM 认证的 XML 和相关技术开发人员。
- XML 技术库:developerWorks XML 专区提供了大量技术文章和技巧、教程、标准以及 IBM 红皮书。
- developerWorks 技术活动和网络广播:通过这些活动了解技术的最新发展。
- developerWorks
podcasts:收听面向软件开发人员的有趣访谈和讨论。
获得产品和技术
- Apache FOP:下载面向您的平台的最新版本。单击左侧的
Download。 xsltproc:下载面向 UNIX 和 Linux 系统的最新版本。- DocBook DTD:下载最新版本并立即开始使用。
- DocBook XSL Stylesheets:下载最新版本(找到 DocBook Project site > file releases 并选择 docbook-xsl)。
xmlto:如果您的系统上没有最新版本,可以下载这个最新版本。根据所运行的 UNIX 或 Linux 版本,您可能还需要下载和安装 Bash, the Bourne-Again shell、GNU find and friends 和 mktemp。- IBM Java SDK:下载面向自己平台的开发工具箱。可能还需要下载和安装 IBM Java SDK 以便在某些 UNIX 和 Linux 发布版上安装和使用 Apache FOP 格式化程序。
-
IBM 产品评估试用软件:下载或 在 IBM SOA Sandbox 研究在线试用版 并尝试使用来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。
讨论
- 参与论坛讨论。
- XML 专区讨论论坛:参与和 XML 相关的几个讨论。
- developerWorks blogs:参与这些 blogs 并加入 developerWorks 社区。