在Darwin信息分类体系结构中的专门化--准备基于主题的DITA文档

2002-8-19 16:21:17【作者】 畅享网 【进入论坛】
广告

在 Darwin 信息分类体系结构中的专门化

--准备基于主题的 DITA 文档


Michael Priestley (
mpriestl@ca.ibm.com)

IBM 公司

2001 年 3 月

 本文深入研究了用于模块化文档产品且基于 XML 的 Darwin 信息分类体系结构(DITA),它告诉如何准备基于主题的 DITA 文档。这份说明涵盖了创建新主题类型和类型间的转换。附录中概述了专门化的规则。本文假设您已经了解了 DITA 是什么;如果需要关于 DITA 的基本介绍,请参阅姐妹篇 -- 介绍 Darwin 信息分类体系结构。

基于 XML 的 Darwin 信息分类体系结构(DITA)是为了创建模块化技术文档,例如,帮助集、手册、用于小屏幕设备的层次结构总结等等,这些使用多种显示和交付机制的技术文档很容易重用。本文说明了如何将 DITA 的原理付诸于实践。

专门化是由作者和体系结构设计者定义新主题类型,同时保持与现有样式表、转换和过程兼容的过程。相对于现有主题类型,以扩展或增加定义新主题类型,因此减少了定义和维护新类型所必需的工作。

本文使用的示例采用了 XML DTD 语法和 XSLT;如果需要关于这方面的背景知识,请参阅参考资料。

结构体系上下文

在 SGML 中,结构体系表单是提供从一个文档类型到另一个文档类型映射的典型方式。对于更棘手的问题,如提供从较具体的主题类型到较常规的主题类型的映射,专门化提供了类似于体系结构表单的解决方案。因为具体主题类型实际上是由常规主题类型发展而来,专门化可以忽略体系结构体系提出的许多棘手问题。这个限定的领域使得专门化过程相对容易实现和维护。专门化还支持多层次或是有层次结构的专门化,这就允许对于较常规的主题类型可以充当不同具体类型的共同点。

体系结构表单允许在两个或多个具有同等结构的文档类型之间来回转换。专门化允许专门化文档类型向较常规的文档类型的单向转换。体系结构表单假设所涉及的文档类型支持同等结构,而专门化假设一个主题类型支持其它结构的子集。

尽管专门化的原理和过程还适用于其它领域,但创建专门化过程的目的是使用 DITA。 如果考虑这个例子,就会更清楚其中的含义:给定专门化和一个普通 DTD(如 HTML),就可以创建一个新的文档类型(称之为 MyHTML)。 在 MyHTML 中,可以为公司实施网站的标准(包括关于表单布局的具体规则、标题行以及使用的字体和闪烁的标识符)。另外,可以对产品和订购信息提供较具体的结构以使搜索引擎和其它应用程序能够更加有效地使用该数据。

DITA 将 MyHTML 定义成 HTML DTD 的扩展,仅在必要时声明新元素类型,对于共享的元素,引用 HTML 的 DTD。MyHTML 无论在哪里声明新元素,它都包括一个到现有 HTML 元素的映射。这个映射允许创建 HTML 的样式表和转换 HTML -- 等同于在 MyHTML 文档上的操作。如果要以不同的方式处理结构(例如,以特殊方式格式化产品信息)时,可以定义一个新的具有扩展行为的样式表或转换,然后导入标准的样式表或转换来处理余下的部分。换言之,可以扩展原始样式表或模式来添加新行为,同样,扩展原始 DTD 或模式来添加新约束。

专门化信息类型

Darwin 信息分类体系结构与其说是文档类型还不如说是信息类型。文档被认为是由许多具有各自信息类型的主题组成。简言之,主题是由标题和一些文本组成的、并被随意分割成几个章节的一段信息。该信息类型描述了主题的内容:例如,所给主题的类型可能是“概念”或“任务”。

DITA 有三种类型的主题:普通主题、或信息型概念、任务和引用主题。概念、任务和引用主题 (reftopics) 都可以看作是主题的专门化。

图 1. 作为主题的专门化的三类信息类型


附加的信息类型可以作为此三种基本类型的任何一种的专门化添加至体系结构,而且这些专门化可以依次被专门化:

图 2. 已扩展的体系结构以合并更多专门的类型


每个新的信息类型都定义成现有信息类型的扩展部分:专门的类型继承了而不是复制任何公共结构;而且专门的类型提供了在它的新元素和常规类型的现有元素之间的映射。每个信息类型都用它自己 DTD 模块定义,这个模块仅定义那种类型的新元素。只有一个信息类型的文档(例如,在帮助 Web 里的任务文档)有一个定义由信息类型的专门化层次结构中的所有模块定义的文档类型。带有多个信息类型(例如,包括概念、任务和 reftopics 的书)的文档类型包括每一个信息类型所用的模块,以及它们父类的模块。

因为信息类型声明被分成多个模块,在不影响父类的情况下可以定义新的信息类型。此分割有以下好处:

减少维护成本:每个编写组仅维护它唯一需要的元素

增加兼容性:核心的信息类型能够集中维护,用所有专门类型反映到核心类型的变化

分布控制:复用性由重用者控制而不是由编写者来控制;添加新类型不影响核心类型的维护,也不影响其他用户的不同类型

任何信息型主题属于多个类型。例如,更笼统地讲,API 描述是一个引用主题。

专门化示例:引用主题

考虑引用主题的专门化层次结构:

图 3. 一个简单的专门化层次结构


表 1 显示了在 topic 中的一般元素和在 reftopic 中的具体元素之间的关系。在这个表中,列、行和单元分别代表信息类型、元素映射和元素。表 2 详细说明了这个关系,有助于您理解表 1。

表 1. 主题和基于它的专门化的关系

Topic

Reftopic

(topic.mod)

(reftopic.mod)

topid

reftopec

title

 

body

refbody

dl

properties

 

section

synsect

refsect


表 2.如何解释表 1.

结构 联系

列 正如在 topic.mod 这个 DTD 模块所声明的,Topic 列显示了基本的 topic 结构,它包括 title 和带可选项 body。Reftopic 列显示了更专门化的结构,用 reftopic 替换 topic、refbody 替换 body 以及 synsect 和 refsect 替换 section;在 reftopic.mod 这个 DTD 模块中声明了这些新元素。

行 每一行代表该行内元素间的映射。在 Reftopic 列的元素专门化了 Topic 列的元素。每个常规元素也作为同一行中的更专门化元素的一个类。 例如, reftopic 的 synsect 是一种 section.

单元 联系它左边的单元,列中的每个单元表示以下的可能性:

空白单元:左边单元的元素作为 -- 是 -- 重用。例如, reftopic title 和 topictitle 是一样的,reftopic 可以使用 title 元素 的 topic 的声明。

填满的单元:对于当前类型是具体的元素替换左边较常规的元素。例如,在 reftopic 中,refbody 替换较常规的 body。

拆分的行:两个或更专门化的元素替换左边较常规的元素。例如, reftopic 用较具体的 synsect(syntax) 和 refsect替换 section。

带空白单元的拆分行:新专门化是除了在专门化类型中仍然可用的较常规元素。例如, reftopic 作为定义清单(dl)的特殊类型添加属性,但dl 的常规类型在 reftopic 中仍然可用。 

reftopic 类型模块

清单 1 并未说明真正的 reftopic 内容,而是基于表 1 的一个简化版本。

清单 1. reftopic.mod

<!ELEMENT reftopic (title, prolog?, refbody,(%info-types;)* )>
<!ELEMENT refbody ((refsect | refsyn|properties)*)>
<!ELEMENT properties ((dthd,ddhd?)|ddhd)?, (dlentry)+) >
<!ELEMENT refsect (%section;)* >
<!ATTLIST refsect label CDATA #IMPLIED>
<!ELEMENT refsyn (%section;)* >
<!ATTLIST refsyn label CDATA #IMPLIED>

这里大多数内容模块声明取决于在 topic.mod 中声明的元素或实体。因而,如果增强或改变 topic 的结构, 大多数的改变将由 reftopic 自动进行。同样,regtopec 的定义也很简单:它毋须重新声明与 topic 共享的任何内容。

添加专门化属性

为显示元素的映射,我们对每个元素添加属性,这些元素显示它到较常规类型的映射。

清单 2. reftopic.mod(第 2 部分)

<!ATTLIST reftopic spec CDATA "topic reftopic">
<!ATTLIST refbody spec CDATA "topic.body reftopic.refbody">
<!ATTLIST properties spec CDATA "topic.dl reftopic.properties">
<!ATTLIST synsect spec CDATA "topic.section reftopic.synsect">
<!ATTLIST refsect spec CDATA "topic.section reftopic.refsect">

随后,我们将讨论在编写 XML 转换时,如何利用这些属性。

创建一个编写的 DTD

既然已经定义了类型模块(它声明了新的分类元素和它们的属性)并且添加专门化的属性(此属性将新类型映射到其父类),我们就可以汇编编写 DTD。

清单 3. reftopic.dtd

<!--Redefine the infotype entity to exclude other topic types-->
<!ENTITY % info-types "reftopic">
<!--Embed topic to get generic elements -->
<!ENTITY % topic SYSTEM "topic.mod"> %topic;
<!--Embed reftopic to get specific elements -->
<!ENTITY % reftopic SYSTEM "reftopic.mod">
%reftopic;

专门化示例:API 描述

现在让我们创建一个更专门化的信息类型:API 描述,它是一种引用主题(所以专门化)。

图 4. 更专门化的信息类型,API 描述


表 3 显示了称之为 APIdesc 信息类型的专门化的一部分,用于API 描述。如上所述,每一列都代表从左到右有专门化发生的信息类型。即,每个信息类型都是它左边相邻的专门化。每一行都代表一组映射的元素,右边(较具体的元素)映射到左边(较常规的相对应的元素)。

如上所述,每个单元专门化该单元左边的内容。

空白单元:左边的元素是未改变的新类型。 例如,在 API 中有 dl 和 synsect。

填满的单元:较具体的元素替换左边的元素。例如,APIname 替换 title。

带拆分行的空白单元:新元素添加至左边的元素中。例如,API 描述添加 synsection 和 refsection元素的同级 -- usage 部分。

表 3. APIdesc 专门化概述

Topic

Reftopic

APIdesc

(topic.mod)

(reftopic.mod)

(APIdesc.mod)

topic

reftopic

APIdesc

title

 

APIname

body

refbody

APIbody

dl

properties

parameters

 

 

section

synsect

 

refsect

 

usage

 

APIdesc 模块

在这您会看到 API 描述的内容实际上比常规引用主题受更多的限制。语法的顺序是用法、参数,后面跟着可选的附加部分。此顺序是在引用主题中允许结构的子集,它允许语法、属性和部分的任何顺序。另外,用法 section 的标签现在固定为 Usage,而不是可选的或作者所定义的,如 refsect 的标签。

清单 4. APIdesc.mod

<!ELEMENT APIdesc (APIname, prolog?, APIbody,(%info-types;)* )>
<!ELEMENT APIname ((%title.cnt;)*)>
<!ELEMENT APIbody (refsyn,usage,parameters,refsect*)>
<!ELEMENT usage (%section;)* >
<!ATTLIST usage label CDATA #FIXED "Usage">
<!ELEMENT parameters ((dthd,ddhd?)|ddhd)?,(dlentry)+) >

添加专门化属性

现在每个新元素都有到其所有父类元素的映射。请注意, APIname 在 reftopic 和 topic 中明确地标明了它的同等体,尽管它们在两种情况下是一样的(title)。这种标识使得跟踪复杂映射的过程很容易。即便您的专门化层次结构达 10 层甚至更多,属性仍然能清晰地表示到每个父信息类型的映射。

清单 5. APIdesc.mod (第二部分)

<!ATTLIST APIdesc spec CDATA "topic reftopic APIdesc" >
<!ATTLIST APIname spec CDATA "topic.title reftopic.title APIdesc.APIname" >
<!ATTLIST APIbody spec CDATA "topic.body reftopic.refbody APIdesc.APIbody" >
<!ATTLIST parameters spec CDATA "topic.dl reftopic.properties APIdesc.parameters">
<!ATTLIST usage spec CDATA "topic.section reftopic.refsect APIdesc.usage">

编写 DTD

既然我们已经定义了类型模块(它声明了新分类的元素和它们的属性)并且添加专门化的属性(此属性将新类型映射到其父类),我们就可以汇编编写 DTD。

清单 6. APIdesc.dtd

<!--Redefine the infotype entity to exclude other topic types-->
<!ENTITY % info-types "APIdesc"><!--Embed topic to get generic elements -->
<!ENTITY % topic SYSTEM "topic.mod"> %topic;
<!--Embed reftopic to get more specific elements -->
<!ENTITY % reftopic SYSTEM "reftopic.mod"> %reftopic;
<!--Embed APIdesc to get most specific elements -->
<!ENTITY % APIdesc SYSTEM "APIdesc.mod"> %APIdesc;

进行专门化

在定义了专门化的类型和声明了必要的属性之后,它们可以为下列操作提供基础:

对专门化主题类型应用常规样式表或转换

概括专门化类型的主题(将其转换成更一般的主题类型)

专门化常规类型的主题(将其转换成较具体的主题类型 -- 仅用于当主题最初是以专门化格式编写且已经经过常规的步骤而未打破其原始格式的约束)

应用常规样式表或转换

因为以新信息类型(例如 APIdesc)编写的内容有到同等体的映射或在先前存在的信息类型(例如 reftopic)里有较少的限制性结构,所以先前存在转换和过程可以安全地应用于新内容。缺省情况下,在新信息类型中每一个专门化元素都被视作其常规同等体的实例。例如,在 APIdesc 中,<usage> 元素将被视作主题 <section> 元素,此元素恰巧有个固定标签 "Usage"。

为了覆盖这个缺省行为,作者可以对该元素类型简单地创建一个新的、更专门化的规则,然后导入缺省样式表或转换,因而就可以扩展该行为而无须直接编辑原始样式表或转换。这种通过引用的重用减少了维护成本(每一个站点仅维护它唯一需要维护的规则)和增加了一致性(因为核心转换规则可以集中维护,而且对核心规则的更改将反映在所有其它将它们导入的转换中)。重用的控制从转换的作者移向了转换的重用者。

本章节余下部分涉及到 XSLT 知识、XSL 转换语言。

要求

只有常规转换已经能处理专门化元素而且专门化元素包含足够的常规转换处理它们所需的信息时,这个过程才起作用。

要求 1:映射属性

为了提供专门化信息,需要添加专门化属性,如先前概述。在文档包含了这些属性之后,它们就可以由支持专门化的转换进行处理了。

要求 2:支持专门化转换

对于转换,需要模板规则以检验元素名称和属性值之间的匹配。

可以用两种方法中的一个完成检验。可以为两个匹配创建单一转换规则,如清单 7 所示。

清单 7. 合并的接口

<xsl:template match="dl|*[contains(@spec,"topic.dl"]">
<!--matches either a dl, or any element that has a spec attribute

that mentions topic.dl -->
<!--do something-->
<xsl:apply-templates/>
</xsl:template>

或者可以用这样一种方式来编写转换,仅在模板匹配语句(不是在循环或条件语句)和所有过程递归发生时,匹配才发生。然后可以为处理专门化命名模板、创建完整的并行接口。

清单 8. 基本接口

<xsl:template match="dl" name="topic.dl">
<!--matches a dl, or can be called by name-->
<!--do something-->
<xsl:apply-templates>
</xsl:template

清单 9. 支持专门化的接口

<xsl:template match="*[contains(@spec,"topic.dl"]">
<!--matches any element that has a spec attribute that mentions
 topic.dl, then calls the dl template by name-->
<!--do something-->
<xsl:call-template name="topic.dl">
</xsl:template>

示例:覆盖转换

对于具体元素,为了覆盖常规转换,新信息类型的作者可以创建一个转换,该转换对专门化元素声明了新行为并且导入常规转换以便为其它元素提供缺省行为。

例如,除了 parameters 以外,APIdesc 专门化转换对所有专门化元素允许缺省处理:

清单 10. APIdesc 专门化转换

<xsl:import href="general-transform.xsl"/>
<xsl:template match="parameters|*[contains(@spec,"APIdesc.parameters"]">
<!--do
something-->
<xsl:apply-templates/>
</xsl:template>

当先前存在的 reftopic properties 模板规则与新 parameters 模板规则遇到 parameters 元素,它们相互匹配,(因为 parameters 元素是 reftopic properties 元素的专门化类型)。然而,由于 parameters 模板是在 importing 样式表里,新模板具有优先权。

常规化主题

因为专门化信息类型也是它的父类的实例(APIdesc 即是 reftopic 也是主题),可以安全地将专门化主题转化为它的较常规父类之一。如果想从两个源文档合并多组文档,每个文档都已经各自专门化了,这种向上的兼容性是有用的:父类提供一个两者都可以安全转换到的公共点。当必须通过不支持专门化的过程添入主题时:例如,使用不支持 DTD 软件的翻译中心也许想支持仅一种文档类型,这种兼容性也许也有用。

为了安全地常规化主题,需要一种能从信息类型到目标信息类型映射的方法。也需要一种能够保留原始类型以防以后需要返回时的方法。

前面介绍的 spec 属性有两个用途。它提供:

需要映射的信息

保留信息以允许返回的方法

专门化的每一层都有其自己的一组 spec 属性,该属性最终为所有专门化元素提供全部的专门化层次结构。

考虑清单 11 中的 APIdesc 主题。

清单 11. 从 APIdesc 的样本主题

<APIdesc>
<APIname>AnAPI</APIname>
<APIbody>

<synsection>AnAPI (parm1, parm2)</synsection>
 <usage label="Usage">Use AnAPI to pass parameters to your process.

</usage>
 <parameters >
 ...
 </parameters>
</APIbody>
</APIdesc>

揭示了 spec 属性(DTD 提供了所有值作为缺省值):

清单 12. 和从 APIdesc 的样本主题一样的示例(包含 spec 属性)

<APIdesc spec="topic reftopic APIdesc">
<APIname spec="topic.title reftopic.title APIdesc.APIname">AnAPI
</APIname>
<APIbody spec="topic.body reftopic.refbody APIdesc.APIbody">

<synsect spec="topic.section reftopic.synsection">AnAPI(parm1,  parm2)</synsection>
 <usage spec="topic.section reftopic.section APIdesc.usage"
 label="Usage">
 <p>Use AnAPI to pass parameters to your process.</p>
 </usage>

<parameters spec="topic.dl reftopic.properties APIdesc.parameters" >
 ...
 </parameters>
</APIbody>
</APIdesc>

从这里,单一模板可以将整个 APIdesc 主题转换成 reftopic 或者普通的主题。模板规则简单地查看一下父元素名称的 spec 属性,并重命名当前元素以便匹配。只要没有 spec 属性(如 <p>),模板规则不会改变元素。

转换成主题后,代码应象清单 13 所示。

清单 13. 来自 APIdesc 的已转换主题

<topic spec="topic reftopic APIdesc">
<title spec="topic.title reftopic.title APIdesc.APIname">AnAPI
</title>
<body spec="topic.body reftopic.refbody APIdesc.APIbody">

<section spec="topic.section reftopic.synsect">AnAPI(parm1,
 parm2)</section>
 <section spec="topic.section reftopic.refsect APIdesc.usage"
 label="Usage">

<p>Use AnAPI to pass parameters to your process.</p>

</section>
 <dl spec="topic.dl reftopic.properties APIdesc.parameters" >
 ....
 </dl>
</body>
</topic>

甚至在常规化后,支持专门化转换可以继续把主题当作 APIdesc,因为转换可以在 spec 属性中查找关于元素类型层次结构的信息。

因此可以通过逆向转换以来回转换(在 spec 属性中查找专门化元素名称和重命名当前元素以匹配)。当没有 spec 属性(<p>),不改变元素;当 spec 属性没有列出目标(第一个 section 没有 APIdesc 值),元素变为列出的最后一个值(所以,确切地讲,第一个 section 成为 synsect)。

然而,如果任何人改变内容结构,而它是普通的 topic(通过改变 section 的次序),在专门化信息类型(其在 APIdesc 情况下加强 APIbody 中特殊序列的信息)下结果可能不再有效。所以,虽然映射到较常规类型总是安全的,但映射回专门化类型会有问题:专门化类型有更多使内容专门化的规则。但是当内容以较常规方式编码时,不会实施这些规则。

专门化主题

如果最初内容是以专门化类型编写,那么专门化常规主题相对琐碎些。然而,如果在想更精确地分类的常规层编写内容,那么情况回很复杂。

例如,假设您创建了一组引用主题。然后,分析了内容后,发现您有一致的模式。现在,您想用专门化信息类型(例如,API 描述)加强这个模式并描述它。为了 专门化,首先需要创建目标 DTD,然后把足够的信息添加到内容中以允许移植它。

可以把专门化信息放在下面两个地方的其中之一:

把它添加到 spec 属性。需要仔细地得到正确的次序和包括所有的父类值。
给出在 classif 属性中的目标元素的名称,基于值移植,随后添加 spec 属性。
在任何一种情况中,在移植前可以运行校验转换以查找相应的属性,然后核实在专门化内容模型下元素的内容是有效的。可以使用类似于 Schematron 的工具来生成验证的转换和移植的转换,或者可以先移植再使用专门化 DTD 来验证移植是成功的。

用模式专门化

类似于 XML DTD 语法,XML Schema 语言是一种定义词汇表(元素和属性)和一组该词汇表上的约束(如内容模型或固定的对隐式的属性)的方式。它有内置的专门化机制,这包括限制允许专门化的能力。使用 XML Schema 语言代替 DTD 使验证代表有效普通类型子集的专门化信息类型变得更容易,这确保通过普通翻译和发布转换能够平稳地处理。

与 DTD 不同,XML 模式以 XML 文档表示。因而, 能够以 DTD 不能的方式处理它们。例如,我们可以 维护单一 XML 模式,然后使用 XSL 生成两个版本:

创作版本 -- 去掉固定的属性和任何覆盖的元素

准备处理的版本 -- 包含翻译和发布转换的 spec 属性

然而,XML 模式还不十分流行,不能全身心地采用它。 主要问题是缺乏创作工具和所采用标准的实现间尚不兼容。在以后几年,当标准最终确定,模式得到广泛地应用和支持时,业界将修复这些问题。

结束语

可以使用这个常规过程来创建专门化信息类型:

标识所需要的元素。

标识到较常规类型元素的映射。

验证专门化元素的内容模型比它们常规的等价部分更具限制性。

创建一个类型模块文件,该文件具有专门化的元素和属性声明(包括 spec 属性)。

创建导入适当类型模块的编写 DTD 文件。

使用这个常规过程来创建专门化 XML 转换:

为您的信息类型创建新转换。

导入想要扩展的现有转换。

标识需要特殊处理的元素。

添加与这些元素相匹配的模板规则,按元素名称和 spec 属性内容。

附录:专门化的规则

在常规 DTD 中,虽然可以创建用于任何标记的新元素同等体,但这项工作对于作者是没有用处的,除非还要专门化包含标记的内容模型。在 APIdesc 示例中,parameters 元素在 topic 或 reftopic 中的任何地方是无效内容。如果 使用它,必须为 parameters 创建自始至终地达到主题级容器地有效上下文。为了向您的作者显示 parameters 元素,需要专门化以下部分:

body 元素,允许 parameters 作为有效的内容(给我们 APIbody)

topic 元素,允许专门化 body(给我们 APIdesc)

当我们移向模式时,可以消除多米诺效应,模式可以辨别专门化元素以及在允许其常规等同体的任何位置允许它们。然而,目前为了彻底专门化需要自始至终直到主题级专门化。

为了确保专门化元素比它们的常规同等体更有约束性(即,它们允许常规同等体允许的真子集结构),需要查看常规元素的内容模型。可以放心地更改您的专门化元素的内容模型,如表 A 显示:

表 A. 专门化规则的总结

内容类型

允许的专门化

示例(特殊的专门化常规)

必需的

只有重命名

<!ELEMENT General(a)>

<!ELEMENT Special(a.1)>

可选的 (?)

重命名,必需做,或删除

<!ELEMENT General(a?)>

 

<!ELEMENT Special(a.1?)>

<!ELEMENT Special(a.1)>

<!ELEMENT Special EMPTY>

一个或多个 (+)

重命名,必需做,分割成要求的元素加上其它的,分割成一个或多个加上其它。

<!ELEMENT General(a+)>

<!ELEMENT Special(a.1+)>

<!ELEMENT Special(a.1)>

<!ELEMENT Special(a.1,a.2,a.3+,a.4*)>

<!ELEMENT Special(a.1+,a.2,a.3*)>

零或多个 (*)

重命名,必需的,可选的,分割成要求的元素加上其它,分割成可选的元素加上其它的,分割成一个或多个加上其它,分割成零或更多加上其它,或删除

<!ELEMENT General(a*)>

<!ELEMENT Special(a.1*)>

<!ELEMENT Special(a.1)>

<!ELEMENT Special(a.1?)>

<!ELEMENT Special(a.1,a.2,a.3+,a.4*)>

<!ELEMENT Special(a.1?,a.2,a.3+,a.4*)>

<!ELEMENT Special(a.1+,a.2,a.3*)>

<!ELEMENT Special(a.1*,a.2?,a.3*)>

<!ELEMENT Special EMPTY>

两者选一

重命名,或选择一个

<!ELEMENT General (a|b)>

<!ELEMENT Special (a.1|b.1)>

<!ELEMENT Special (a.1)>

 
扩展的示例


有个常规元素 General,具有内容模型 (a,b?,(c|d+))。这个定义表示 General 总是包含元素 a,接着的元素 b 是可选的,且总是以 c 或者一个或多个 d 来结束。

清单 A. 常规元素 General 的内容模型

<!ELEMENT General (a,b?,(c|d+))>

当专门化 General 以创建 Special 时,它的元素必须相同或 有更多限制:不允许它比 General 做更多的事,或者不能向上映射或保证常规处理、转换或样式表的正确行为。

暂搁重命名(它总是被允许的 -- 它只意味着还可以专门化 Special 包含的一些元素), 这里是可以对 Special 的内容模型进行有效更改,导致同样或更多限制的内容规则:

清单 B. 模型 Special 的有效更改,使 b 强制

<!ELEMENT Special (a,b,(c|d))>

Special 现在需要 b 出现,而不是可选的,而且仅允许一个 d。它安全地映射至 General。

清单 C. 模型 Special 的有效更改,使 c 强制而且不允许 d

<!ELEMENT Special (a,b?,c)>


Special 现在需要c 出现,而不再允许 d 出现。它安全地映射至 General。

清单 D. 模型 Special 的有效更改,改变 d 强制地三个专门化

<!ELEMENT Special (a,b?,d1,d2,d3)>

Special 现在要求 d 的三个专门化出现而不允许 c 出现。它安全地映射至 General。

参考资料

请阅读 developerWorks 上的介绍 Darwin 信息分类体系结构

发现如何参加由 Don Day 和 Michael Preistley 主持的 DITA 论坛的讨论,。

直接进入由 Don Day 和 Michael Preistley 主持的 DITA 论坛

下载 DITA DTDs、样式表、样本文档

需要 XSLT 的背景知识吗?请阅读 Michael Kay 的技术介绍,XSLT 是什么类型的语言?或参阅 Doug Tidwell 由三部分组成的 XML 转换教程,它描述了从 XML 到 HTML 、 PDF 和 SVG 的转换(可伸缩的向量图形)。

关于作者

Michael Priestley 是 IBM Toronto Software Development Laboratory 的信息开发者。他写了大量有关,如超文本导航、singlesourcing 和动态文档接口的文章。他目前在做用于帮助和文档管理的 XML 和 XSL。

如果您希望与本文章的作者或其所在机构,进一步交流,请联系:畅享网 姜小姐
jill.jiang@amteam.org | 021-51096826-112 | 在线联系
老孙的IT运维管理之道[原创]用户的BSM用户的IT业务管..

从企业实际的IT运营角度来看,BSM是推动IT与业务融合,实现、改善WCNG司IT管理和治理的最佳实践之一。

吕建伟 专栏和CIO问答软件项目实施管理

现实中很少能按照正规流程来的,所以只能把流程中的各个环节拆开,个个击破,以后就可以见招拆招了。

ITIL实施:CIO时刻准备着

千军易得,一将难求,要推进ITIL实施,CIO扮演的角色不容忽视。吹响集结号,CIO出击的时刻已经来到。

节能与优化IT 企业CIO过冬良策

当前金融危机的影响还在继续漫延,很多企业都在苦寻过冬的良策,在这种情况下,节能与优化技术与产品无疑成为CIO们关注的首要对象,本次选题就是针对节能与优化IT来为CIO们提供过冬的良……