标题：dtd
简介
文档类型定义（DTD）可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。
DTD 可被成行地声明于 XML 文档中，也可作为一个外部引用。内部的 DOCTYPE 声明假如 DTD 被包含在您的 XML 源文件中，它应当通过下面的语法包装在一个 DOCTYPE 声明中：
*****************************************************************************
<!DOCTYPE 根元素 [元素声明]>
*****************************************************************************
带有 DTD 的 XML 文档实例
*****************************************************************************
<?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>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend</body>
</note>
*****************************************************************************
以上 DTD 解释如下：
!DOCTYPE note (第二行)定义此文档是 note 类型的文档。
!ELEMENT note (第三行)定义 note 元素有四个元素："to、from、heading,、body"
!ELEMENT to (第四行)定义 to 元素为 "#PCDATA" 类型
!ELEMENT from (第五行)定义 from 元素为 "#PCDATA" 类型
!ELEMENT heading (第六行)定义 heading 元素为 "#PCDATA" 类型
!ELEMENT body (第七行)定义 body 元素为 "#PCDATA" 类型外部文档声明假如 DTD 位于 XML 源文件的外部，那么它应通过下面的语法被封装在一个 DOCTYPE 定义中：
<!DOCTYPE 根元素 SYSTEM "文件名">
这个 XML 文档和上面的 XML 文档相同，但是拥有一个外部的 DTD: 
*****************************************************************************
<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note> 
这是包含 DTD 的 "note.dtd" 文件：
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
*****************************************************************************为什么使用 DTD通过 DTD，您的每一个 XML 文件均可携带一个有关其自身格式的描述。
通过 DTD，独立的团体可一致地使用某个标准的 DTD 来交换数据。
而您的应用程序也可使用某个标准的 DTD 来验证从外部接收到的数据。
您还可以使用 DTD 来验证您自身的数据。
模块
XML 以及 HTML 文档的主要构建模块是类似 <body>....</body> 这样的标签。
XML 文档构建模块
所有的 XML 文档（以及 HTML 文档）均由以下简单的构建模块构成：
元素 
属性 
实体 
PCDATA 
CDATA 
下面是每个构建模块的简要描述。
元素
元素是 XML 以及 HTML 文档的主要构建模块。
HTML 元素的例子是 "body" 和 "table"。XML 元素的例子是 "note" 和 "message" 。元素可包含文本、其他元素或者是空的。空的 HTML 元素的例子是 "hr"、"br" 以及 "img"。
实例：
*********************************************************
<body>body text in between</body>
<message>some message in between</message>
*********************************************************
属性
属性可提供有关元素的额外信息。
属性总是被置于某元素的开始标签中。属性总是以名称/值的形式成对出现的。下面的 "img" 元素拥有关于源文件的额外信息：
*********************************************************
<img src="computer.gif" />
*********************************************************
元素的名称是 "img"。属性的名称是 "src"。属性的值是 "computer.gif"并且可以用样式来控制大小等显示效果。由于元素本身为空，它被一个 " /" 关闭。
实体
实体是用来定义普通文本的变量。实体引用是对实体的引用。
大多数同学都了解这个 HTML 实体引用：" "。这个“无折行空格”实体在 HTML 中被用于在某个文档中插入一个额外的空格。
当文档被 XML 解析器解析时，实体就会被展开。
PCDATA
PCDATA 的意思是被解析的字符数据（parsed character data）。
可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。
PDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。
文本中的标签会被当作标记来处理，而实体会被展开。
不过，被解析的字符数据不应当包含任何 &、< 或者 > 字符；需要使用 &amp; 、&lt; 以及 &gt; 实体来分别替换它们。
CDATA
CDATA 的意思是字符数据（character data）。
CDATA 是不会被解析器解析的文本。在这些文本中的标签不会被当作标记来对待，其中的实体也不会被展开。
元素
在一个 DTD 中，元素通过元素声明来进行声明。
声明一个元素
在 DTD 中，XML 元素通过元素声明来进行声明。元素声明使用下面的语法：
<!ELEMENT 元素名称 类别>
或者
<!ELEMENT 元素名称 (元素内容)>
空元素
空元素通过类别关键词EMPTY进行声明：
<!ELEMENT 元素名称 EMPTY>
只有 PCDATA 的元素
只有 PCDATA 的元素通过圆括号中的 #PCDATA 进行声明：
<!ELEMENT 元素名称 (#PCDATA)>
带有任何内容的元素
通过类别关键词 ANY 声明的元素，可包含任何可解析数据的组合：
<!ELEMENT 元素名称 ANY>
带有子元素（序列）的元素
带有一个或多个子元素的元素通过圆括号中的子元素名进行声明：
<!ELEMENT 元素名称 (子元素名称 1)>
或者
<!ELEMENT 元素名称 (子元素名称 1,子元素名称 2,.....)>相同的元素至少出现一次的声明语法格式为:
<!ELEMENT element-name (child-name+)> 
例:
<!ELEMENT note (message+)>
例中的+是指子元素message必须在被包含的note元素里出现一次或者多次。相同的元素不出现或者多次出现的声明语法格式为:
<!ELEMENT element-name (child-name*)>
例:
<!ELEMENT note (message*)>
例中的*是指子元素message能够在被包含的note元素里不出现或者出现多次。相同的元素不出现或者出现一次的声明语法格式为: 
<!ELEMENT element-name (child-name?)>
例:
<!ELEMENT note (message?)>
例中的?是指子元素message能够在被包含的note元素里不出现或者出现一次。
属性
在 DTD 中，属性通过 ATTLIST 声明来进行声明。
声明属性
属性声明拥使用下列语法：
<!ATTLIST 元素名称 属性名称 属性类型 默认值>
以下是属性类型的选项：
类型描述
CDATA 值为字符数据 (character data) 
(en1|en2|..) 此值是枚举列表中的一个值 
ID 值为唯一的 id 
IDREF 值为另外一个元素的 id 
IDREFS 值为其他 id 的列表 
NMTOKEN 值为合法的 XML 名称 
NMTOKENS 值为合法的 XML 名称的列表 
ENTITY 值是一个实体 
ENTITIES 值是一个实体列表 
NOTATION 此值是符号的名称 
xml: 值是一个预定义的 XML 值 
默认值参数可使用下列值：
值 解释
值 属性的默认值 
#REQUIRED 属性值是必需的 
#IMPLIED 属性不是必需的 
#FIXED value 属性值是固定的 
规定一个默认的属性值
DTD:
<!ELEMENT square EMPTY>
<!ATTLIST square width CDATA "0">
合法的 XML:
<square width="100" />
在上面的例子中，"square" 被定义为带有 CDATA 类型的 "width" 属性的空元素。如果宽度没有被设定，其默认值为0 。
实体
实体是用于定义引用普通文本或特殊字符的快捷方式的变量。
实体引用是对实体的引用。
实体可在内部或外部进行声明。一个内部实体声明语法：
<!ENTITY 实体名称 "实体的值">
DTD 例子：
<!ENTITY writer "Bill Gates">
<!ENTITY copyright "Copyright 具体的url">XML 例子：
<author>&writer;&copyright;</author>注释: 一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 (;)。一个外部实体声明语法：
<!ENTITY 实体名称 SYSTEM "URI/URL">
DTD 例子：
<!ENTITY writer SYSTEM "具体的url">
<!ENTITY copyright SYSTEM "具体的url">XML 例子：
<author>&writer;&copyright;</author>
DTD实例
报纸文章<!DOCTYPE NEWSPAPER [ 
<!ELEMENT NEWSPAPER (ARTICLE+)>
<!ELEMENT ARTICLE (HEADLINE,BYLINE,LEAD,BODY,NOTES)>
<!ELEMENT HEADLINE (#PCDATA)>
<!ELEMENT BYLINE (#PCDATA)>
<!ELEMENT LEAD (#PCDATA)>
<!ELEMENT BODY (#PCDATA)>
<!ELEMENT NOTES (#PCDATA)> 
<!ATTLIST ARTICLE AUTHOR CDATA #REQUIRED>
<!ATTLIST ARTICLE EDITOR CDATA #IMPLIED>
<!ATTLIST ARTICLE DATE CDATA #IMPLIED>
<!ATTLIST ARTICLE EDITION CDATA #IMPLIED>
<!ENTITY NEWSPAPER "Vervet Logic Times">
<!ENTITY PUBLISHER "Vervet Logic Press">
<!ENTITY COPYRIGHT "Copyright 1998 Vervet Logic Press">
]>产品目录:<!DOCTYPE CATALOG [
<!ENTITY AUTHOR "John Doe">
<!ENTITY COMPANY "JD Power Tools, Inc.">
<!ELEMENT CATALOG (PRODUCT+)>
<!ELEMENT PRODUCT
(SPECIFICATIONS+,OPTIONS?,PRICE+,NOTES?)>
<!ATTLIST PRODUCT
NAME CDATA #IMPLIED
CATEGORY (HandTool|Table|Shop-Professional) "HandTool"
PARTNUM CDATA #IMPLIED
PLANT (Pittsburgh|Milwaukee|Chicago) "Chicago"
INVENTORY (InStock|Backordered|Discontinued) "InStock">
<!ELEMENT SPECIFICATIONS (#PCDATA)>
<!ATTLIST SPECIFICATIONS
WEIGHT CDATA #IMPLIED
POWER CDATA #IMPLIED>
<!ELEMENT OPTIONS (#PCDATA)>
<!ATTLIST OPTIONS
FINISH (Metal|Polished|Matte) "Matte" 
ADAPTER (Included|Optional|NotApplicable) "Included"
CASE (HardShell|Soft|NotApplicable) "HardShell">
<!ELEMENT PRICE (#PCDATA)>
<!ATTLIST PRICE
MSRP CDATA #IMPLIED
WHOLESALE CDATA #IMPLIED
STREET CDATA #IMPLIED
SHIPPING CDATA #IMPLIED>
<!ELEMENT NOTES (#PCDATA)>
]>图书馆:<!DOCTYPE books [
<!--公共标识符："-//LIBRARY//BDATA/DTD/BOOKDTD"--><!ENTITY % attrib "(every|default)"><!--设定类型的临时实体--><!ELEMENT books (book*)><!--图书馆图书元素--><!ELEMENT book (name,id,attrib+,description?,writer?,corp?,comment?)><!--一本图书的元素--><!ELEMENT name (#PCDATA)><!--名字--><!ELEMENT id EMPTY><!--ID（空）--><!ATTLIST id id ID #REQUIRED><!--ID属性--><!ELEMENT attrib EMPTY><!--类型（空）--><!ATTLIST attrib attrib %attrib; "default"><!--类型属性--><!ELEMENT description (#PCDATA)><!--描述--><!ELEMENT writer (#PCDATA)><!--作者--><!ELEMENT corp (#PCDATA)><!--出版社--><!ELEMENT comment (#PCDATA)><!--注释--><!ENTITY library "Our Library"><!--定义图书馆产权实体-->
]>
优劣
DTD的优势每一个XML文档都可携带一个DTD，用来对该文档格式进行描述，测试该文档是否为有效的XML文档。既然DTD有外部和内部之分，当然就可以为某个独立的团体定义一个公用的外部DTD，那么多个XML文档就都可以共享使用该DTD，使得数据交换更为有效。甚至在某些文档中还可以使内部DTD和外部DTD相结合。在应用程序中也可以用某个DTD来检测接收到的数据是否符合某个标准。
对于XML文档而言，虽然DTD不是必须的，但它为文档的编制带来了方便。加强了文档标记内参数的一致性，使XML语法分析器能够确认文档。如果不使用DTD来对XML文档进行定义，那么XML语法分析器将无法对该文档进行确认。
元素的定义 
根元素的声明 
每个XML文档都只有一个根元素，其它的子元素都包含在该根元素中。因此在DTD中对根元素的声明是必不可少的。根元素声明的一般形式如下：
<!DOCTYPE root[ 
<!-- 子元素 --> ]>
<!-- 文件体 --> 
DOCTYPE是“document type”（文档类型）的简写，DOCTYPE声明必须放在文档最顶部，在所有代码和标识之上，DOCTYPE声明是必不可少的关键组成部分。DTD语法要求DOCTYPE必须要大写，而且DOCTYPE和元素之间必须要有空格隔开。如在以上代码中DOCTYPE和根元素root之间要有空格隔开。DTD的缺陷利用DTD验证有效性的解析器，就能够立即对文档的完整性进行可靠的检查。DTD虽然比较实用，但DTD也有不少的缺陷。
DTD有自己的特殊语法，其本身不是XML文档；
DTD只提供了有限的数据类型，用户无法自定义类型；
DTD不支持域名机制。