DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。
DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。
为什么使用 DTD?
通过 DTD,您的每一个 XML 文件均可携带一个有关其自身格式的描述。
通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据。
而您的应用程序也可使用某个标准的 DTD 来验证从外部接收到的数据。
您还可以使用 DTD 来验证您自身的数据
假如 DTD 被包含在您的 XML 源文件中,它应当通过下面的语法包装在一个 DOCTYPE 声明中:
外部文档声明
假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:
XML 文档构建模块
所有的 XML 文档(以及 HTML 文档)均由以下简单的构建模块构成:
- 元素
- 属性
- 实体
- PCDATA
- CDATA
PCDATA
PCDATA 的意思是被解析的字符数据(parsed character data)。
可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。
PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。
文本中的标签会被当作标记来处理,而实体会被展开。
不过,被解析的字符数据不应当包含任何 &、< 或者 > 字符;需要使用 &、< 以及 > 实体来分别替换它们。
CDATA
CDATA 的意思是字符数据(character data)。
CDATA 是不会被解析器解析的文本。在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。
只有 PCDATA 的元素通过圆括号中的 #PCDATA 进行声明:<!ELEMENT from (#PCDATA)>
通过类别关键词 ANY 声明的元素,可包含任何可解析数据的组合:<!ELEMENT note ANY>
带有一个或多个子元素的元素通过圆括号中的子元素名进行声明:<!ELEMENT note (to,from,heading,body)>
当子元素按照由逗号分隔开的序列进行声明时,这些子元素必须按照相同的顺序出现在文档中。在一个完整的声明中,子元素也必须被声明,同时子元素也可拥有子元素。
声明只出现一次的元素:<!ELEMENT note (message)>
message 子元素必须在 "note" 元素内出现至少一次:<!ELEMENT note (message+)>
子元素 message 可在 "note" 元素内出现零次或多次:<!ELEMENT note (message*)>
子元素 message 可在 "note" 元素内出现零次或一次:<!ELEMENT note (message?)>
声明"非.../既..."类型的内容:<!ELEMENT note (to,from,header,(message|body))>
上面的例子声明了:"note" 元素必须包含 "to" 元素、"from" 元素、"header" 元素,以及非 "message" 元素既 "body" 元素。
声明混合型的内容:<!ELEMENT note (#PCDATA|to|from|header|message)*>
上面的例子声明了:"note" 元素可包含出现零次或多次的 PCDATA、"to"、"from"、"header" 或者 "message"。
声明属性
属性声明使用下列语法: <!ATTLIST element-name attribute-name attribute-type attribute-value> DTD 实例: <!ATTLIST payment type CDATA "check"> XML 实例: <payment type="check" />
列举属性值
语法
<!ATTLIST element-name attribute-name (en1|en2|..) default-value> 实例 DTD: <!ATTLIST payment type (check|cash) "cash"> XML 例子: <payment type="check" /> 或 <payment type="cash" /> 如果您希望属性值为一系列固定的合法值之一,请使用列举属性值。
你应该避免使用属性?
一些属性具有以下问题:
- 属性不能包含多个值(子元素可以)
- 属性不容易扩展(为以后需求的变化)
- 属性无法描述结构(子元素可以)
- 属性更难以操纵程序代码
- 属性值是不容易测试,针对DTD
如果您使用属性作为数据容器,最终的XML文档将难以阅读和维护。 尝试使用元素来描述数据。只有在提供的数据是不相关信息时我们才建议使用属性。
一个内部实体声明
DTD 实例:
<!ENTITY writer "Donald Duck.">
<!ENTITY copyright "Copyright W3CSchool.cc">
XML 实例:
<author>&writer;©right;</author>
一个外部实体声明
DTD 实例:
<!ENTITY writer SYSTEM "http://www.w3cschool.cc/entities.dtd">
<!ENTITY copyright SYSTEM "http://www.w3cschool.cc/entities.dtd">
XML example:
<author>&writer;©right;</author>
DTD的实际例子:
<!DOCTYPE CATALOG [ <!ENTITY AUTHOR "John Doe"> <!ENTITY COMPANY "JD Power Tools, Inc."> <!ENTITY EMAIL "jd@jd-tools.com"> <!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)> ]>