解码 XML 和 DTD(资料)

未显示需要 JavaScript
的文档选项

级别: 初级

Jane Fung, VisualAge for Java 支持, IBM 加拿大

2001 年 7 月 01 日


篇介绍性文章说明了如何创建 XML“文档类型定义(DTD)”和格式正确定义明确的 XML 文件,这些文件能够由您选择的 XML
语法分析器进行确认。虽然不必在产生的每个 XML 文件中都包含 DTD,但这样做将会使您的生活大为轻松。DTD 不仅强制使用为 XML
文件建立的语法,它还将允许文件由确认 XML 语法分析器进行语法分析。代码样本包括 DTD 和 XML 文档示例。

“可扩展标记语言”已经存在了十分长的一段时间,因此现在大多数人都熟悉其最基本的需求:所有
XML 文档都必须既格式正确又有效。但如何确定您的 XML
文档是否满足这些需求呢?简短的回答就是您不用确定。或者至少是不必。大多数时候,您会依赖于
XML 语法分析器来为您管理这些苦活。

在经过一些小调查(请参阅

参考资料)后您就会发现市场上到处充斥着 XML
语法分析器,其中大多数都可以从 Web 上免费获得。一个基本的 XML
语法分析器既强调 XML
语法规则(即,确保文件格式正确),又建立文件的有效性。XML
语法分析器可用于几乎每种相关的计算机语言,包括
C、C++、Perl、Python、Tcl 和 Java。

谈到确保 XML
格式正确时,您可以或多或少地指向一个语法分析器然后执行。然而为了确保文档有效,需要为语法分析器提供文档类型定义或
DTD。

模式如何?

最近,W3C 将长期以来一直讨论的 XML Schema
规范推进成“建议书”状态,这意味着它有可能为开发人员普遍所用。在某些方面,XML
Schema 将替代 DTD。而在其它方面,DTD 仍是最好的解决方案。有关解释
XML Schema,以及将它与 DTD 进行功能和处理上的对比的 developerWorks
文章,请参阅

参考资料

本文回顾了 XML
文档格式正确究竟意味着什么,然后会谈到较少讨论的话题确认 -
更具体地说,是 DTD。我将讨论为什么您需要将 DTD 包含在 XML
文件中、介绍一些最常用的 DTD
语法,并使用几个简单的样本来教您开始编写自己的 DTD。

为什么要格式正确?

当 XML 开发人员谈到格式正确和格式不正确的 XML
时,我们并不是参加美学讨论。当然,格式正确的 XML
文档是满足以下三个基本结构需求的文档:

  • 有一个包含所有其它元素的父(或根)元素
  • 每个开始标记都有结束标记
  • 所有元素都正确嵌套的

清单 1 是一个格式正确的 XML 示例。请注意:该文档的父元素是

<person> ,每个开始标记都有一个结束标记,并且每个结束标记都有与其开始标记完全相同的定义。通常,开始标记和结束标记之间包括的是信息或文本。不过,在某些情况下,标记之间没有包括信息或文本。空标记必须用一个右斜杠来结束。


<nothing/>
就是一个空标记。

清单 1. 格式正确的 XML

<person>
<firstname>Jane</firstname>
<lastname>Fung</lastname>
<nothing/>
</person>

清单 2 是一个格式不正确的 XML
示例。它举例说明了三种常见错误。首先,开始和结束

<firstname>
标记没有完全匹配。其次,

<lastname>
标记没有结束标记。最后,空标记没有用一个右斜杠结束。

清单 2. 格式不正确的
XML

<person>
<Firstname>Jane</firstname>
<lastname>Fung
<nothing>
</person>

回页首

DTD
中有什么内容?

XML
的优点在于它允许您定义自己的有意义的标记,因此您可以最大程度地定制文档。但
XML 就是
XML(可扩展),而人就是人(疯狂的人),这可能很快就会无法控制。解决方案是
DTD,它指定了 XML 文档的标记。简而言之,DTD
指定:可以在文档中存在的元素、那些元素可以具有的属性、在元素内部元素的层次结构以及元素在整个文档中出现的顺序。

虽然 DTD 不是必需的,但它们确实带来方便。DTD
适合三个基本用途。它能:

  • 对标记编制文档
  • 加强标记参数内部的一致性
  • 使 XML 语法分析器能够确认文档

如果不对 XML 文档进行 DTD 定义,文档就无法由 XML
语法分析器进行确认。使用 XML Schema 实例来代替 DTD
如何?(请参阅侧栏

模式如何?)清单 3 是清单 1
中显示的 XML 文档的 DTD。

清单 3. 精简 person.xml 的
DTD

<!ELEMENT person (firstname, lastname)>
<!ELEMENT firstname (#PCDATA)>
<!ELEMENT lastname (#PCDATA)>
<!ELEMENT nothing EMPTY>

关于示例的几点说明

清单 3 中 DTD 的第一行定义了 XML
文档的父元素:

person 。person
元素有两个子元素:

firstname

lastname

第二和第三行包含了元素属性

#PCDATA ,它表明

firstname

lastname
元素可能包含经过语法分析的字符数据(在这种情况下是文本)。DTD
文件的最后一行描述了一个空标记:

nothing

从清单 3 中的 DTD 可以看出,任何阅读我们的 XML
文档的人(以及对它进行语法分析的语法分析器)都知道

person 元素仅包含两个文本元素:

firstname

lastname 。此外,DTD
规定,在整个文档中,

firstname 元素必须在

lastname 元素之前出现。

在转到更复杂的示例之前,让我们回顾一下一些最常用的 DTD
语法元素。可以在 W3C 主页上找到完整的 DTD 规范(请参阅

参考资料)。


回页首

DTD
语法快速指南

A、B、C 和 D 是在下例中代表元素的变量。

元素必须有正好一个

A 、至少一个

B (由加号表示)、零个或多个

C (由星号表示)以及零个或一个

D (由问号表示):

<!ELEMENT element (A, B+, C*, D?)>

元素可能有

A

B

C
之一:

<!ELEMENT element (A | B | C)>

元素不包含任何内容:

<!ELEMENT element EMPTY>

元素可以包含在 DTD 中列出的任何元素:

<!ELEMENT element ANY>

元素可能包含经过语法分析的字符数据或另一个元素(

element2 )。星号(*)表示混合内容模型 — 其中元素可以包含不同类型的属性。

<!ELEMENT element (#PCDATA|element2)*>

下例将文本 "entity reference" 插到文档中它出现的任何地方:

<!ENTITY element "entity reference">

可以看到在 XML 文档中该实体引用元素如下:

&element;

下例表明其元素是一个包含三个属性的空标记:属性
1(

att1 )是一个可选属性,属性
2(

att2 )是带有固定值

"A" 的属性,属性
3(

att3 )是必需的文本属性。

   <!ELEMENT element EMPTY>


<!ATTLIST element
att1 ID #IMPLIED
att2 CDATA #FIXED "A"
att3 CDATA #REQUIRED>


可以看到在 XML 文档中使用的这个元素如下:

<element att2="A" att3="MustHave"/>

属性

CDATA
表示包括的信息应该是文本。

ID
属性表明必须填入唯一的标识。每个元素只能有一个

ID
属性。另外,

CDATA 表示

att2

att3 可能包含任何字符串。

如果您对该语法还未完全熟悉,请继续阅读。下一部分中的工作示例应该能帮助您消除疑虑。


回页首

工作示例

可以使用 Microsoft Internet Explorer 5 或更高版本查看清单 4
中显示的 XML 文档 ― 前面示例中使用的 people.xml
文件的扩展版本。如果在 IE5 中打开
people.xml,应该看到一个树结构。这是因为 IE5 带有能够将 XML
文档语法分析成元素树的 XML 语法分析器。

还可以在

参考资料中找到这个文件及其
DTD。

清单 4. people.xml
的完整清单

<?xml version="1.0"?>
<!DOCTYPE people SYSTEM "people.dtd">
<people>
<person>
<name>
<firstname>Jane</firstname>
<lastname>Fung</lastname>
</name>
<look>good-looking</look>
<possession>
<car>
<model>Civic</model>
</car>
<job>&IBM;</job>
</possession>
</person>
<person>
<name>
<firstname>G.I.</firstname>
<lastname>Jane</lastname>
</name>
<look>tough</look>
<possession>
<house country="CANADA" city="Toronto">
<townhouse townhouse_type="good" />
</house>
<bankaccount bankaccount_number="sg-123">

<![CDATA[<greeting>5000</greeting>]]>
</bankaccount>
</possession>
<other>
<car>she has a car</car>
<house country="CANADA" city="Toronto">
<townhouse townhouse_type="good" />
</house>
</other>
</person>
</people>

关于 XML 的几点说明

对 XML 的深入探讨主要考虑的是文档头中的几个元素,从以下开始:

<?xml version="1.0"?>

每个 XML 文档都必须包含这样的一个头,向 XML
语法分析器表示它是一个 XML 文档。头中的下一行告诉 XML
语法分析器该文档是使用什么字符编码来创建的:

<!DOCTYPE people SYSTEM "people.dtd">

在 Unix 系统上创建的 XML 文档和在 Windows 系统上创建的 XML
文档可能有不同的编码。

还可以为第一行设置可选的

standalone
属性。standalone 的缺省值是

no

no 值表示该 DTD
定义是在另一个文件中描述的。

yes 值表明该 DTD 应该在 XML
文档内部定义。我没有为示例设置这个属性;如果想设置,它应该看起来如下:

   <?xml version="1.0" standalone='yes'?>
<!DOCTYPE people [
<!ELEMENT people (person+)>
<!ELEMENT person (#PCDATA)>
]>

还应该注意使这个文档格式正确的方法。例如,所有空标记都用一个右斜杠结束,如下所示:

<townhouse townhouse_type="good" />

还请注意

CDATA 用于对所有若不进行转义就会以 XML 语言解释的任何数据进行转义,例如:

<![CDATA[<greeting>5000</greeting>]]>

如果适当的格式化,这一行将以文本内容显示:

<greeting> 5000 </greeting>

可以从 XML 文件的进一步研究中获益,甚至可能从对您自己的文件运行
XML 语法分析器获益(请参阅

参考资料)。但是现在,让我们看一下 people.xml
文件的 DTD。

清单 5. people.dtd
的完整清单

<!ELEMENT people (person+)>
<!ELEMENT person (name, look*, possession?, other?)>
<!ELEMENT name (firstname, lastname)>
<!ELEMENT firstname (#PCDATA)>
<!ELEMENT lastname (#PCDATA)>
<!ELEMENT look (#PCDATA)>
<!ELEMENT possession (car?, house?, bankaccount?, job?)>
<!ELEMENT car (#PCDATA|model)*>
<!ELEMENT model (#PCDATA)>
<!ELEMENT house (apartment|standalone|townhouse)>
<!ATTLIST house house_area ID #IMPLIED country CDATA #FIXED
"CANADA" city CDATA #IMPLIED>
<!ELEMENT apartment EMPTY>
<!ELEMENT standalone EMPTY>
<!ELEMENT townhouse EMPTY>
<!ATTLIST townhouse townhouse_type ID #IMPLIED>
<!ELEMENT bankaccount (#PCDATA)>
<!ATTLIST bankaccount bankaccount_number ID #REQUIRED>
<!ELEMENT job (#PCDATA)>
<!ELEMENT other ANY>

<!ENTITY IBM "Proud to work for IBM">

关于 DTD 的几点说明

使用

快速指南作为参考,通过比较 XML 文件及其
DTD,您应该能够方便地定义 DTD 和 XML
文件中各元素之间的关系。不过,还有两个剩下的元素,您可能感兴趣。

清单 4 包含了对实体的引用。

<job>&IBM;</job>

实体引用用于代替在 DTD
文档中定义的特定字符或字符串。进行了语法分析后,该实体引用将读作:

<job> Proud to work for IBM </job>

还应该注意,

<other> 标记的内容类型是

ANY 。这表示

<other>
可能包含所有以前已在 DTD 中声明过的元素。因此,

other
元素可能包含

car

house
元素,如下:

   <other>
<car>she has a car</car>
<house country="CANADA" city="Toronto">
<townhouse townhouse_type="good" />
</house>
</other>

回页首

结束语

这就结束了对创建格式和定义均正确的 XML
文件的基本介绍。您可能想要继续自己研究 people.xml 和 people.dtd
文件。如果想要尝试使用 XML
语法分析器对这些文件进行语法分析,请参阅“参考资料”来查找可供下载的语法分析器的列表。


回页首

参考资料

  • 您可以参阅本文在 developerWorks 全球站点上的

    英文原文.

  • 如果希望了解有关 XML 和 DTD 语法的更多信息,

    XML
    1.0 W3C Recommendation
    应该是您的第一站。

  • Tim Bray 是 XML 1.0 规范的原始编辑之一。他维护着

    Textuality.com,可以在上面找到他关于
    XML、DTD 等内容思想。还可以找到 Lark 和 Larval,Bray 自己的 XML
    语法分析器。

  • Doug Tidwell 的


    教程:XML 简介
    展示了对“可扩展标记语言”近乎完整的探讨。

  • 您可能还想要仔细查看 Mark Johnson 在 JavaWorld 上发表的


    XML for the absolute beginner
    一文。

  • 请下载本文示例中使用的

    people.xml

    people.dtd文件,以进一步研究和分析。

XML 语法分析器:简表

  • IBM 的


    XML Parser for Java
    (XML4J),目前是版本 3.1.1,是以 100% 纯
    Java 编写的确认 XML 语法分析器。包(com.ibm.xml.parser)包含了对
    XML 文档进行语法分析、生成、操纵和确认的类和方法。

  • IBM 的


    XML for C++ parser
    (XML4C) 基于 Apache 的 Xerces-C XML
    语法分析器,它是用 C++ 的可移植子集编写的确认 XML 语法分析器。

  • XML::Parser
    是 Perl 扩展模块,充当与

    expat的接口。

  • TclXML
    是全 Tcl 的 XML 语法分析器。

  • Xerces 是来自
    Apache Software Foundation 的 Java 语法分析器,目前是版本
    1.4.0。

  • Lars Marius Goshol 负责维护作为公众服务的这个详尽的


    XML 语法分析器列表
    和其它 XML 工具。

相关链接

  • XML
    专区页面
    上查看最新信息。

  • 如同 DTD,在创建 XML
    文件时,样式表不是必需的,但如果希望控制浏览器中文档显示,它们就非常重要。Alan
    Knox 的 developerWorks 文章,

    Style sheets can
    write style sheets, too
    ,向您介绍如何使用 XSL 来将 XML
    数据转换成用于浏览器的复杂显示标记。

  • 阅读完上述文章后,可能想要查看 IBM alphaWorks 的


    XSL Editor

  • 如果希望探索 XML Schema 以及它与 DTD 的关系,请参阅 David Mertz
    在其 developerWorks 专栏“XML 问题 7”中的

    DTD 和 XML
    Schema 比较
    ,以及 Kevin Williams 的 developerWorks 临时讲台


    赞同使用 XMLSchema 的文章
    来了解用于数据的 XML
    文档的结构化定义。有关使用 XML Schema
    会怎样的简短说明,请参阅介绍性文章


    Basics of using XML Schema to define elements


回页首

关于作者

author

Jane Fung 目前在 IBM VisualAge for Java
技术支持小组工作,该小组为使用 VisualAge for Java
的企业开发人员提供支持。Jane
获得了加拿大安大略省的沃特卢大学电子工程应用科学学士学位,并且是一名
Sun Java 2 认证程序员。可以通过
jcyfung@ca.ibm.com 与 Jane
联系。


回页首
Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: