本文章内容转载自 W3school DTD 教程
DTD 是什么
文档类型定义(DTD)可以定义合法的XML文档构建模块。
所有 XML 文档均由以下构建模块构成:
- 元素
- 属性
- 实体
- PCDATA
- CDATA
DTD 的作用
- 通过 DTD,每一个 XML 文件均可携带一个有关其自身格式的描述
- 通过 DTD,独立的团体可以一致地使用某个标准的 DTD 来交换数据
- 通过 DTD,应用程序可以验证自身的数据和从外部接收到的数据
DTD 的内部声明
如果 DTD 位于 XML 源文件的内部,使用以下语法:
<!DOCTYPE 根元素 [元素声明]>
例如:
<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
!DOCTYPE note(第二行)定义此文档是 note 类型的文档。
!ELEMENT note(第三行)定义 note 元素有四个子元素:“to、from、heading、body”。
!ELEMENT to(第四行)定义 to 元素为 “#PCDATA” 类型。
DTD 的外部声明
如果 DTD 位于 XML 源文件的外部,使用以下语法:
<!DOCTYPE 根元素 SYSTEM "文件名">
例如:
<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
这是包含 DTD 的 “note.dtd” 文件:
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
DTD 声明元素
元素声明,使用以下语法:
<!ELEMENT 元素名称 类型>
空元素声明,使用以下语法:
<!ELEMENT 元素名称 EMPTY>
带有任何内容的元素声明,使用以下语法:
<!ELEMENT 元素名称 ANY>
带有子元素的元素声明,使用以下语法:
<!ELEMENT 元素名称 (子元素名称 1,子元素名称 2,...)>
- ? 表示出现零次或一次
- * 表示出现零次或多次
- + 表示至少出现一次
- | 表示只能出现其中之一
例如以下,“note” 元素必须包含 “to” 元素、“from” 元素、“header” 元素,以及非 “message” 元素既 “body” 元素。
<!ELEMENT note (to,from,header,(message|body))>
DTD 声明属性
属性声明,使用以下语法:
<!ATTLIST 元素名称 属性名称 属性类型 默认值>
属性类型 | 描述 |
CDATA | 属性值是 Unparsed Character Data |
(enum1 | enum2 | ...) | 属性值是枚举列表中的某一个 |
ID | 属性值在文档中唯一 |
IDREF / IDREFS | 属性值是其他元素的 ID |
NMTOKEN / NMTOKENS | 属性值是 Name Token |
ENTITY / ENTITIES | 属性值是一个实体 |
NOTATION | 属性值是符号的名称 |
-
ID 表示属性值在文档中 必须是唯一的,属性值不能包含空格
<!ELEMENT verse (#PCDATA)> <!-- 元素可以同时定义多个属性,属性之间用空格分隔 --> <!ATTLIST verse rhyme ID #REQUIRED category CDATA #IMPLED> <verse rhyme="游"> <verse rhyme="收"> <verse rhyme="秋"> <verse rhyme="头"> <verse rhyme="不">
-
IDREF 表示属性值是文档中 其它元素的 ID 类型属性的值,属性值不能包含空格
-
IDREFS 表示属性值由多个用空格分隔的 IDREF 类型的属性值组成
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sheet [ <!ELEMENT sheet (category +)> <!ATTLIST sheet id ID #REQUIRED name CDATA #REQUIRED> <!ELEMENT category (word *)> <!ATTLIST category id ID #REQUIRED s_id IDREF #REQUIRED name CDATA #REQUIRED> <!ELEMENT word (#PCDATA)> <!ATTLIST word c_id IDREFS #REQUIRED name CDATA #REQUIRED> ]> <!-- 常用韵表有平水韵和中华新韵,类别使用id属性标记 --> <sheet id="平水韵" name="韵表"> <!-- 平水韵有106个韵部,类别使用id属性标记 --> <category id="五物" s_id="平水韵" name="韵部"></category> <category id="十一尤" s_id="平水韵" name="韵部"> <!-- "不"属于"十一尤"和"五物"2个韵部 --> <word c_id="十一尤 五物" name="韵字">不</word> </category> </sheet>
-
NMTOKEN 是 Name Token 的简写,表示 属性值由字母、数字、句号、连字符、下划线、冒号(非首字符)组成,属性值不能包含空格
-
NMTOKENS 表示属性值由多个用空格分隔的 NMTOKEN 类型的属性值组成
<?xml version="1.0" encoding="UTF-8"?> <!-- 内部声明DTD,定义此文档是poem类型的文档 --> <!DOCTYPE poem [ <-- 定义poem元素有3个子元素title, author, content必须按照指定顺序都出现 --> <!ELEMENT poem (title, author, content)> <!-- 定义title元素类型为"#PCDATA" --> <!ELEMENT title (#PCDATA)> <!ELEMENT author (#PCDATA)> <!-- 定义author元素必须有一个NMTOKEN类型的属性,属性名dynasty --> <!ATTLIST author dynasty NMTOKEN #REQUIRED> <!ELEMENT content (#PCDATA)> ]> <poem> <title>梦微之</title> <author dynasty="中唐">白居易</author> <content> 夜来携手梦同游,晨起盈巾泪莫收。 漳浦老身三度病,咸阳草树八回秋。 君埋泉下泥销骨,我寄人间雪满头。 阿卫韩郎相次去,夜台茫昧得知不。 </content> </poem>
-
ENTITY 表示属性值是 在 DTD 中声明的实体名称,可以将外部二进制数据和外部不可解析实体(例如GIF、JPEG、AVI等格式文件)链接到文档中
-
ENTITIES 表示属性值由多个用空格分隔的 ENTITY 类型的属性值组成
-
NOTATION 表示属性值是 在 DTD 中声明的记号名称,对于不可解析的实体,通过该关键字声明支持的应用
<!NOTATION jpg SYSTEM "image/jpeg"> <!-- 声明外部实体,实体名称为baijuyi。NDATA表示实体有相应的NOTATION类型 --> <!ENTITY baijuyi SYSTEM "baijuyi.jpg" NDATA jpg> <!-- 声明author元素的photo属性,类型为ENTITY类型 --> <!ATTLIST author dynasty NMTOKEN #REQUIRED photo ENTITY #IMPLIED> <!-- 在属性中引用实体 --> <author dynasty="中唐" photo="baijuyi">白居易</author>
-
#REQUIRED 表示属性值是必需的
语法:
<!ATTLIST 元素名称 属性名称 属性类型 #REQUIRED>
例子:
<!ATTLIST verse rhyme CDATA #REQUIRED> <!-- 合法 --> <verse rhyme="游" /> <!-- 非法 --> <verse />
-
#IMPLIED 表示属性值不是必需的
语法:
<!ATTLIST 元素名称 属性名称 属性类型 #IMPLIED>
例子:
<!ATTLIST verse category CDATA #IMPLED> <!-- 合法 --> <verse category="十一尤" /> <!-- 合法 --> <verse />
-
#FIXED value 表示属性值是固定的
语法:
<!ATTLIST 元素名称 属性名称 属性类型 #FIXED "value">
例子:
<!ATTLIST verse category CDATA #FIXED "十一尤"> <!-- 合法 --> <verse category="十一尤" /> <!-- 非法 --> <verse category="五物"/>
DTD 声明实体
实体是用来定义一个变量,通过这个变量可以方便的引用普通文本或外部的二进制数据。
实体可以在内部或外部进行声明。
-
内部声明,使用以下语法:
<!ENTITY 实体名称 "实体的值">
例如:
<!ENTITY writer "Bill Gates"> <!ENTITY copyright "Copyright W3School.com.cn">
-
外部声明,使用以下语法:
<!ENTITY 实体名称 SYSTEM "URI/URL">
例如:
<!ENTITY writer SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd"> <!ENTITY copyright SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">
在 XML 中通过实体引用来引用 DTD 中声明的实体:
<author>&writer;©right;</author>