文档对象模型(DOM)是一种面向有效 HTML 和符合规范的 XML 文档的应用程序编程接口(API)。它定义了文档的逻辑结构以及访问和操作文档的方式。在 DOM 规范中,“document”(文档)一词使用的是宽泛的含义——XML 正日益被用来表示可存储在各种系统中的许多不同类型的信息,而这些信息传统上更被视为数据而非文档。尽管如此,XML 将这些数据表现为文档,且可以使用 DOM 来管理这些数据。
借助文档对象模型,程序员可以创建文档、遍历其结构,并添加、修改或删除元素和内容。HTML 或 XML 文档中的任何内容都可以使用文档对象模型进行访问、修改、删除或添加,只有少数例外——特别是,XML 的内部子集和外部子集的 DOM interfaces 尚未被指定。
作为 W3C 规范,文档对象模型的一个重要目标是提供一个可在各种环境和 applications 中使用的标准编程接口。DOM 设计为可与任何编程语言一起使用。为了提供精确、与语言无关的 DOM 接口规范,我们选择使用对象管理组(OMG)IDL [OMGIDL],该 IDL 在 CORBA 2.3.1 规范 [CORBA] 中定义。除 OMG IDL 规范外,我们还为 Java [Java] 和 ECMAScript [ECMAScript](一种基于 JavaScript [JavaScript] 和 JScript [JScript] 的行业标准脚本语言)提供 language bindings。
注意: OMG IDL 仅作为一种语言无关、实现中立的方式来指定 interfaces。本可使用其他多种 IDL(如 [COM]、[JavaIDL]、[MIDL] 等)。通常,IDL 是为特定计算环境设计的。文档对象模型可以在任何计算环境中实现,不要求使用这些 IDL 通常关联的对象绑定运行时。
DOM 是面向文档的编程 API。它基于一种对象结构,该结构与它所 models 的文档结构极为相似。例如,考虑下面这张从 HTML 文档中摘取的表格。
<TABLE>
<TBODY>
<TR>
<TD>Shady Grove</TD>
<TD>Aeolian</TD>
</TR>
<TR>
<TD>Over the River, Charlie</TD>
<TD>Dorian</TD>
</TR>
</TBODY>
</TABLE>
下面是该示例表格的 DOM 的图形化表示:
在 DOM 中,文档具有非常类似树形的逻辑结构;更精确地说,它类似于“森林”或“树丛”,可以包含多个树。每个文档包含零个或一个 doctype 节点、一个根元素节点以及零个或多个注释或处理指令;根元素充当该文档元素树的根。然而,DOM 并未规定文档必须以树或树丛的形式 实现,也未规定对象之间的关系必须如何实现。DOM 是一种逻辑模型,可采用任何方便的方式实现。在本规范中,我们使用术语 structure model 来描述文档的树形表示。当提及通过“树遍历”方法(不包括属性)可以访问的信息项的安排时,也使用“树”一词。DOM 结构模型的一个重要属性是 structural isomorphism:如果使用任意两个 Document Object Model 实现来创建同一文档的表示,它们将生成相同的结构模型,从而符合 XML 信息集 [Infoset]。
注意:根据用于构建 DOM 的解析器不同,可能会出现一些差异。例如,如果解析器丢弃元素内容中的空白字符,则 DOM 中可能不包含这些空白。
之所以选择 “Document Object Model” 这一名称,是因为它在传统面向对象设计意义上是一个 “object model”:文档通过对象进行建模,且该模型不仅涵盖文档的结构,还包括文档的行为以及构成文档的对象。换言之,上图中的节点并不表示数据结构,而是表示具备功能和身份的对象。作为对象模型,DOM 明确了…
SGML 文档的结构传统上是由抽象的 data model 表示,而非对象模型。在抽象的 data model 中,模型围绕数据本身展开。面向对象的编程语言则将数据封装在对象中,隐藏数据本身,防止直接的外部操作。这些对象所关联的函数决定了如何操作对象,它们是对象模型的一部分。
本节旨在通过将 DOM 与其他可能看起来相似的系统区分开来,使读者对 DOM 有更精确的理解。
DOM 最初作为一种规范出现,旨在使 JavaScript 脚本和 Java 程序在 Web 浏览器之间具有可移植性。“动态 HTML”是文档对象模型的直接前身,最初主要被视为浏览器相关的技术。然而,当 W3C 成立 DOM 工作组时,来自其他领域的厂商也加入进来,包括 HTML/XML 编辑器和文档库等。这些厂商中有些早在 XML 出现之前就已经使用 SGML;因此,DOM 受到了 SGML 树丛(Groves)和 HyTime 标准的影响。一些厂商还为 SGML/XML 编辑器或文档库开发了自己的对象模型,这些模型同样对 DOM 产生了影响。
在基本的 DOM 接口中,没有表示实体的对象。数值字符引用以及 HTML 与 XML 中的预定义实体会被对应的单个字符所替代。例如,在下面的例子中:
<p>This is a dog & a cat</p>
“&” 将被替换为字符 “&”,并且 P 元素中的文本将形成一个连续的字符序列。由于数值字符引用和预定义实体在 CDATA 区段以及 HTML 中的 SCRIPT 与 STYLE 元素内不被识别为实体,它们不会被替换为所指的单个字符。如果上述示例被放在 CDATA 区段中,“&” 将不会被替换为 “&”;同样,<p> 也不会被识别为起始标签。普通实体(内部和外部)的表示在 DOM Level 1 的扩展(XML)接口中定义 [DOM Level 1]。
注意:当文档的 DOM 表示被序列化为 XML 或 HTML 文本时,应用程序需要检查文本数据中的每个字符,判断是否必须使用数值实体或预定义实体进行转义。如果未进行此检查,可能导致生成的 HTML 或 XML 非法。此外,implementations 应注意,如果序列化到的字符集(“charset”)未能完整覆盖 ISO 10646,而标记或 CDATA 区段中出现该字符集不支持的字符,则序列化可能会失败。
本节说明了 DOM Level 2 的不同合规级别。DOM Level 2 包含 14 个模块。可以整体符合 DOM Level 2,也可以仅符合其中的某个模块。
如果实现支持本文件中定义的 Core 模块(参见 Fundamental Interfaces),则称其为 DOM Level 2 合规实现。如果实现支持某个 DOM Level 2 模块的全部接口及其语义,则认为它符合该模块。
以下是 DOM Level 2.0 的完整模块列表以及它们使用的特性。特性名称不区分大小写。
注意:截至出版时,该 DOM Level 2 模块尚未成为 W3C 推荐标准。
DOM 实现不得在 hasFeature(feature, version) method 中对该特性返回 "true",除非实现符合相应模块。所有在 DOM Level 2.0 中使用的特性的 version 号均为 “2.0”。
DOM 指定了一套可用于管理 XML 或 HTML 文档的接口。需要认识到这些接口是抽象的——类似于 C++ 中的“抽象基类”,它们用于指定访问和操作应用内部文档表示的方式。接口本身并不暗示特定的具体实现。每个 DOM 应用可以使用任何方便的内部表示来维护文档,只要支持本规范中列出的接口即可。一些 DOM 实现可能是已有的程序,这些程序在 DOM 规范出现之前就已经使用 DOM 接口访问软件。因此,DOM 被设计为避免实现上的依赖,尤其是,
Level 1 接口已被扩展,以同时提供 Level 1 与 Level 2 的功能。
除 Java 与 ECMAScript 外的其他语言的 DOM 实现可以选择适合其语言与运行时环境的绑定方式。例如,某些系统可能需要创建一个从 Document 派生、包含新方法和属性的 Document2 类。
DOM Level 2 并未规定多线程机制。