级别: 初级 Robert D. Anderson (robander@us.ibm.com), 开发人员,Information Development Workbench(IBM 内部工具), IBM Don Day (dond@us.ibm.com), DITA 体系结构主管, IBM Erik Hennum (ehennum@us.ibm.com), 顾问软件工程师, IBM
2005 年 2 月 01 日 Darwin Information Typing Architecture(达尔文信息类型化体系结构,DITA)是作为标准面向主题的文档体系结构出现的。与直接用 HTML 编辑信息相比,DITA 有很多优点,包括更好的重用性、易于改变的表示风格、便于实现资源单一化。本系列文章包括两部分,这是第一部分,介绍了如何用已有的 HTML 主题快速掌握 DITA。它介绍了如何用提供的 XSLT 转换完成迁移,并分析了为保证结果质量需要做什么。
随着 Web 的发明,IBM用 HTML 页面建立了大量文档。为了把这些文档转化成更加易于重用的、面向主题的体系结构,IBM 的很多小组必须将大部分信息迁移到 DITA。
但是迁移过程提出了一个挑战。遗留的内容是使用很多工具创建的,使用了不同的 HTML 样式,因此很难采用通用的迁移过程。除非使用非常严格的 HTML 编辑模板,否则常常会出现某些东西搞乱了简单的迁移工具。
本系列文章包括两部分,描述了我们是如何应对这一挑战的,本文是第 1 部分。第 1 部分主要讨论迁移本身:什么情况下最适合迁移,以及应该怎么做。我们还介绍了在迁移过程中我们学到的一些技术。
这里提供的代码在 IBM 内部用于将 HTML 文章转化成 DITA。虽然很多作者不加修改就使用了这个迁移工具,我们知道不可能总这么幸运。我们通过本文告诉您这是一种通用转换,不可能处理所有的 HTML 文章。很多情况下,文章中已经包含了特殊的标记,很容易与 DITA 结构匹配。在这种情况下,建议您改写迁移以提高效率,保存所有已有的信息体系结构。第 2 部分将详细介绍如何改写迁移工具,得到适应需要的结果。
如果您的 HTML 主题非常简单,又不想为 XSLT 费神,或者期望在 DITA 输出中做清理工作,那么阅读本文就足够了。本文提供的工具可以引领您充分体验 DITA。
如果您希望使用 XSLT 来减少手工清理的劳动量,那么可以把本文看作入门介绍。您还需要知道迁移之前需要做什么,增加扩展之前预期得到什么样的结果。然后您可以阅读第二篇文章,看看 XSLT 是如何组织的,以及如何轻松地跳过默认的迁移。
如果还不熟悉 DITA,以下是两篇很好的入门文章:
什么样的文章适合迁移?
并非所有的 HTML 主题都能够或者需要迁移到 DITA。“为何 DITA 生成 HTML 交付品?”一文给出了不应该转换的一些主题的例子。这些主题包括专用的基于 HTML 的 UI、重在外观而非内容的文章、不需要修改或者重用的蹩脚文章。还有一些主题应该转换,但使用自动化工具不能很好地迁移。这类主题通常是用古老的 HTML 编辑工具编写的,或者单纯为了改进表现形式而大量使用表格、列表和缩进引用。
DITA 体系结构关注的是主题,相对较小的信息片段恰好能放在浏览器窗口中,很少需要滚动窗口。任何已经按照这种方式保存的信息可以更方便地迁移到 DITA。
最佳转换对象是那些使用结构良好的 HTML、或者使用标准编辑模板的主题。
分析内容
内容是否已经按照概念、任务和参考文章划分了?如果没有的话,迁移之前可能要首先对这些文章进行再加工。DITA 文章通常都使用这三种信息类型编辑,或者对不属于任何大类的信息使用更加一般的 topic 类型。如果可能,应尽量直接迁移到这三种具体类型之一,否则此后可能还需要进行一次迁移。
这里讨论的迁移技术包括使用一些常用的工具,如 HTML Tidy 和各种版本的 XSLT。我们将讨论迁移前的清理(如全球编辑或 HTML Tidy)、使用 XSLT 迁移脚本/转换进行向上转换、迁移后验证和修饰。
本文中讨论的基本迁移脚本每次只涉及一种信息类型。如果能够将信息分放到代表三种类型的不同目录中,分组转换就更容易了。我们使用一个批处理工具将给定目录中的每个 HTML 文件都用相同的信息类型转化。如果将每种类型放在不同的目录中,只需要少数指令就能很容易地转化所有的主题。当然,也可以通过编写脚本选择最佳的方式来迁移混合的 HTML 主题目录中的每个文件。
需要清理的项目
该迁移工具只能用于有效的 XHTML 文件,因此多数 HTML 文件都必须在处理之前进行清理。最好的办法是使用 Tidy 命令(请参阅参考资料)。使用 Tidy 的时候,必须让它避开文档类型,以免迁移工具尝试验证每个文件。
转换中丢掉了表示元素 <br/> 和 <hr/>,因为 DITA 没有对应的标签。如果必须使用这些元素向读者传达某种信息,可以寻找其他方法来表示。一种办法是使用预格式化的文本来代替 <br/>,或者使用表格来代替 <hr/> 划分不同段落。这也意味着如果准备转到 DITA,主题通常都需要进行修改。
除了用 Tidy 完成从 HTML 到 XHTML 的必要转换之外,还需要考虑在迁移之前或之后进行其他清理是否更容易一些。最好的办法是首先尝试转换几个样本文件。如果 HTML 包含很容易修改的正规结构,如没有实际意义的 <div> 元素,您可能会发现在转换之前,如果对其加以修改,转换会更容易一些。但是,迁移工具在遇到问题时会发出消息,因而在迁移后发现问题更容易一些。对于迁移后的更新,还可以使用验证编辑器保证清理是有效的。
其他常见的迁移问题
下面这些问题应该牢牢记住:
- 撰写本文的时候,提供的迁移工具只能操作单个文件。它通过一个参数(infotype)接受目标信息类型,并创建相应的主题。infotype 参数的值可以是主题(topic 默认)、任务(task)、概念(concept)或者引用(reference);输出只能是单个文件中的单个值。
- 如果 HTML 内容已经具备了主题体系结构,可以通过将 HTML 迁移到特定的主题类型来转换已有的体系结构。使用更特殊的类型有很多好处,比如在输出中按照类型排列链接。这样做更便于组织表示,而且如果知道要查找的目标也更容易发现信息。在 IBM 中,直接转化成 topic 的用户常常发现后来需要更具体的主题,不得不再进行一次迁移。
- 如果用 XSLT 1.0 进行迁移,doctype 不能包含在输出中。转化到 DITA 后,您还需要 doctype,以便在以后使用该主题。这种情况下有几种不同的选择:
- 使用成批处理程序或者支持跨文件搜索/替换的编辑器手工添加 doctype。
- 创建一个包装器 XSLT 外壳,设置适当的 doctype,并将其导入到迁移中。不同的信息类型需要调用不同的外壳。
- 某些处理程序允许通过变量设置 doctype 来绕过这个问题。比如,Saxon 允许指定 XSLT 1.1,然后动态设置 doctype。
该工具假设您自己设置 doctype,但是也包含利用 Saxon XSLT 1.1 处理能力(也可用于其他处理程序)的代码。如果希望使用 Saxon 的 1.1 层处理能力动态设置 doctype,即使不懂 XSLT 也能很容易地做到这一点。该程序一开始的代码如清单 1 所示:
清单 1. 开头
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no" encoding="utf-8" />
<xsl:param name="infotype">topic</xsl:param>
|
要切换到动态版本,必须对上述代码添加注释符号(即在前面加上 <!--,后面加上 -->)。然后还必须去掉清单 2 所示代码中的注释符号。
清单 2. 动态创建 doctype 的 XSLT 代码
<!--<xsl:stylesheet version="1.1"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:saxon="http://icl.com/saxon"
extension-element-prefixes="saxon">
<xsl:param name="infotype">topic</xsl:param>
<xsl:param name="systemid">
<xsl:choose>
<xsl:when test="$infotype='concept'">../dtd/concept.dtd</xsl:when>
<xsl:when test="$infotype='task'">../dtd/task.dtd</xsl:when>
<xsl:when test="$infotype='reference'">../dtd/reference.dtd</xsl:when>
<xsl:otherwise>../dtd/topic.dtd</xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:param name="publicid">
<xsl:choose>
<xsl:when test="$infotype='concept'">-//IBM//DTD DITA Concept//EN</xsl:when>
<xsl:when test="$infotype='task'">-//IBM//DTD DITA Task//EN</xsl:when>
<xsl:when test="$infotype='reference'">-//IBM//DTD DITA Reference//EN</xsl:when>
<xsl:otherwise>-//IBM//DTD DITA Topic//EN</xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:output method="xml" indent="no" encoding="utf-8"
doctype-system="{$systemid}" doctype-public="{$publicid}"/>--> |
- 转换链接时,本地 HTML 主题的扩展名被改为“.dita”。到外部或者非 HTML 资源的链接保留不动。如果不希望使用“.dita”扩展名,可以使用
dita-extension 参数改变它。只需要传递需要的值(比如 dita-extension=xml),或者在源代码中修改这个值即可。
- DITA 主题必须包含 ID 属性。迁移工具通过分析 HTML 文件的名字(作为参数传入)来决定 ID。如果没有传递 HTML 文件名,则生成一个 ID 使用。如果希望使用其他方法创建主题 ID,比如主题标题或者每个主题开始之处的短语,则应该更新
genidattribute 模板或者修改 filename-id 变量的默认值。
- 一般来说,迁移工具对如何迁移任何给定的元素都能做出最好的猜测。但是某些情况下,数据的现有结构不能可靠地映射到正确的 DITA 元素。只要工具不能确定正确的迁移方式,它就会将内容放在
<required-cleanup> 元素中,并生成一条消息说明输出结果必须是确定的。

 |

|
这种迁移不能做什么?
确定何时使用这种迁移最重要的一点是它用于主题。一个 HTML 页面不应包含相当于书籍中多个章节的内容,而应该只包含没有嵌套其他章节的一小节。如上所述,DITA 体系结构强调的是主题,为书籍编写的信息需要重新设计,以便适应基于主题的体系结构。还可以使用 DITA 映射,在迁移之后通过定义转换后主题之间的嵌套关系来重新建立分层结构。
同样重要的是要记住,这实际上是一种迁移;作为处理管道的一部分并不是很有用。如果遇到的不是面向主题的信息,就不能仅仅通过 DITA 创建真正的主题。HTML 主题迁移到 DITA 后至少还需要做少量的清理。虽然可以对 XSLT 作很大修改来避免清理工作,但是如果下一次某个作者在意料之外的地方插入了 <br/> 标签仍然会带来问题。在长期的运行中,迁移文件、清理 DITA 内容,然后用 CSS 控制任何输出需求要容易得多。
特殊 HTML 技巧的问题
您可能已经发觉,用 HTML 可以对表示作出各种调整,但有时候副作用是歪曲了内容。比如,块引用可能就是块引用,但也可能是希望缩进的一幅图片。结构良好的 HTML 避免使用 <blockquote> 元素,而更倾向于基于 CSS 的表示。DITA 也采用了同样的方法。因此在迁移到 DITA 时,常常需要同时修正标记。
在几个项目中,我们的用户使用 RoboHelp 编写了大量的主题。由于保存有序列表的方法,很多文件都转化不好。每个列表项都放在只包含自身的有序列表中,编号则使用每个列表的 start 属性保存。比如,出现在第五个列表中的第五项表示为 <ol start="5">。对于需要额外空间的列表,每个列表项之间引入空段落。
在 DITA 中,更好的办法是保存成一个列表,然后用 CSS 控制输出的空格。对于任务信息类型这一点尤其重要,因为只能有一个 <steps> 元素,不可能将每个项分解到自己的 <steps> 元素中。
我们通过检查主题看看是否包含带有 start 属性的列表来解决这个问题。如果出现这种列表,就先对主题走一趟复制整棵树,同时合并应该连在一起的列表。如果希望看看这是如何用 XSLT 实现的,可以打开“shift-lists”模式。结果树放在一个变量中,然后像原始文件那样处理该变量的内容。
这种处理变量的方法对某些 XSLT 处理程序可能造成问题(前述的 Saxon 处理程序完全没有问题)。如果处理程序是这种情况,可以将合并的 XHTML 发送到一个临时文件中,然后处理该文件。也可以采用走两趟的模型依次进行转换,或者忽略该问题迁移之后再手工合并。要注意,只有当列表使用 start 属性时才会出现该问题,如果没有这个属性,可以忽略合并过程。
上述过程最初是为 RoboHelp 用户改写的。但是任何有这种标记的人都需要改写,因此我们又将其放回了原来的迁移中。
运行迁移
如果不需要修改 XSLT,那么现在就可以开始执行了,所要做的就是下载 XSLT 到系统中的某个地方。可以使用任何 XSLT 处理程序来转换主题。
运行 XSLT 本身之前,首先要保证文件是有效的 XHTML。最简单的办法就是使用 TIDY 命令(请参阅参考资料)。我们通过几个 Tidy 选项尽量保证 XHTML 是干净的:
表 1. Tidy 命令选项
|
Tidy 选项
|
说明
| -c | 用对 CSS 的引用代替 FONT、NOBR 和 Center 标签。 | -n | 在可能的情况下实体使用数字值而不是命名值。 | -m | 用修改后的文件代替原始文件。如果使用该选项,一定要备份原来的 HTML 文件。 | --output-xml yes | 保证输出是有效的 XML。 | --doctype omit | 防止在输出中出现 doctype。如果输出是 XHTML,可以防止 XSL 解析器在转换之前验证每个 XHTML 主题。 |
比方说,可以这样调用 Tidy:
tidy -c -n -m --output-xml yes --doctype omit input.htm > output.htm |
再说一次,在调用之前不要忘记备份 HTML 文件。这里可以使用批处理文件,在 IBM 内部,我们有一个简单批处理脚本,在目录中创建每个 HTML 文件的副本,然后修改文件。
现在已经得到了有效的 XHTML 主题,然后可以调用 XSLT 来迁移主题了。
- 清单 3 中的调用创建了一项任务,使用生成的 ID 作为任务 ID,用“.dita”作为默认的扩展名:
清单 3. 使用 Saxon 和 Xalan 调用迁移
java com.icl.saxon.StyleSheet mytask.htm h2d.xsl infotype=task > mytask.dita
java org.apache.xalan.xslt.Process -in mytask.htm -xsl h2d.xsl
-out mytask.dita -param infotype task
|
- 清单 4 中的调用创建一个概念,使用文件名作为 ID,“.xml”作为默认的扩展名:
清单 4. 带有更多参数的复杂调用
java com.icl.saxon.StyleSheet myconcept.html h2d.xsl infotype=concept
FILENAME=myconcept.html dita-extension=xml > myconcept.xml
java org.apache.xalan.xslt.Process -in myconcept.html -xsl h2d.xsl -out myconcept.xml
-param infotype task -param filename myconcept.html
-param dita-extension xml |
如果有大批主题需要转换,建立一个批处理文件是不错的办法。我们的批处理文件是用同样的信息类型转换一个目录中的所有主题,就是说在迁移之前我们必须把每种类型先分开。您会发现这是最简单的方法,也可以创建一个批处理文件在迁移每个主题之前首先询问信息类型。
结束语
把主题从 HTML 转化成 DITA 可以带来很多好处。首先,更容易重用主题或部分主题,可以生成多种输出格式,只要改变 CSS 文件就可以迅速改变所有输出文件的表示。如果您还没有被说服,请参阅“为何 DITA 生成 HTML 交付品?”。
如果已经拥有了结构良好的主题,可以找几篇试一试我们提供的转换工具。您会发现,只要很少的人工干预,就可以完全进入以 DITA 为资源的环境。即使对于复杂的 HTML,清理输出结果也费不了多少事。当然,如果您愿意使用 XSLT,一定要阅读本文的第二部分,其中介绍了使用 XSLT 转换的提示和技巧。
下载 | 描述 | 名字 | 大小 | 下载方法 |
|---|
| XSLT migration script and samples | x-dita8asource.zip | 21 KB | HTTP |
|---|
参考资料
- 您可以参阅本文在 developerWorks 全球站点上的 英文原文。
- 通过以下 developerWorks 文章进一步了解 DITA:
- 在 OASIS 主页可以找到更多关于 DITA 的信息。
- 下面是迁移时可以使用的一些工具:
作者简介  | |  | Robert D. Anderson 自 1999 年以来一直从事 IBM 的 Internal Information Development Workbench,编写并维护 SGML (IBMIDDoc) 和 XML (DITA) 的转换工具。自 2001 年以来,他主要从事 DITA 的转换工具以及一般的 DITA 设计(移交给 OASIS 之前)。您可以通过 robander@us.ibm.com 和他联系。 |
 | |  | Don Day 为 IBM Information Development 社区设计发布工具并提供支持,曾代表 IBM 参加了 W3C XSL 和 CSS 工作组。过去三年中,Don 一直领导着曾经开发、现在负责维护 DITA DTD 及其规范的工作组。他从新墨西哥州立大学获得了英语和新闻硕士学位、技术和专业通信博士学位。您可以通过 dond@us.ibm.com 和他联系。 |
 | |  | Erik Hennum 为 IBM Storage Systems Group 设计和实现 User Assistance。在 DITA 方面,他帮助确立了领域专门化的基本原则。您可以通过 ehennum@us.ibm.com 和他联系。 |
对本文的评价
|