DTD
>DTD
DTD(文档类型定义)的作用是XML文档的合法构建模块。
DTD可被成行地声明于XML文档中,也可作为一个外部引用。
DTD可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。
DTD可被成行地声明于XML文档中,也可作为一个外部引用。
一、DTD简介
1.1、内部的DOCTYPE声明
<?xml version="1.0"?> <!DOCTYPE note [ <!-- 定义此文档是note类型的文档 --> <!ELEMENT note (to,from,heading,body)> <!-- 定义note元素有四个元素:"to,from,heading,body" --> <!ELEMENT to (#PCDATA)> <!-- 定义to元素为#"PCDATA"类型 --> <!ELEMENT from (#PCDATA)> <!-- 定义from元素为#"PCDATA"类型 --> <!ELEMENT heading (#PCDATA)> <!-- 定义heading元素为#"PCDATA"类型 --> <!ELEMENT body (#PCDATA)> <!-- 定义body元素为#"PCDATA"类型 --> ]> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend</body> </note>
1.2、外部文档声明
假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:
语法:
<!DOCTYPE root-element SYSTEM "filename">
<?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)>
1.3、为什么使用DTD
通过 DTD,每一个 XML 文件均可携带一个有关其自身格式的描述。
通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据。
应用程序也可使用某个标准的 DTD 来验证从外部接收到的数据。
还可以使用 DTD 来验证xml文件自身的数据。
二、DTD-XML构建模块
2.1、XML文档构建模块
XML 和 HTML文档的主要的构建模块是元素标签。
所有的XML文档(以及HTML文档)均由一下简单的构建模块构成
元素
属性
实体
PCDATA
CDATA
元素
HTML 元素的例子是 "body" 和 "table"。XML 元素的例子是 "note" 和 "message" 。元素可包含文本、其他元素或者是空的。空的 HTML 元素的例子是 "hr"、"br" 以及 "img"。
<body>some text</body> <message>some text</message>
属性:可提供有关元素的额外信息。
属性总是被置于某元素的开始标签中。属性总是以名称/值的形式成对出现的。
<img src="computer.gif" />
元素的名称是 "img"。属性的名称是 "src"。属性的值是 "computer.gif"。由于元素本身为空,它被一个 " /" 关闭。
实体
实体是用来定义普通文本的变量。实体引用是对实体的引用。
HTML 实体引用:" "。这个"无折行空格"实体在 HTML 中被用于在某个文档中插入一个额外的空格。
实体引用 字符
< <
> >
& &
" "
' '
PCDATA
PCDATA (parsed character data) -->被解析的字符数据。
可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本.
PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。
文本中的标签会被当作标记来处理,而实体会被展开。
不过,被解析的字符数据不应当包含任何 &、< 或者 > 字符;需要使用 &、< 以及 > 实体来分别替换它们。
CDATA
字符数据(character data)
CDATA是不会被解析器解析的文本。在这些文本中的标签不被当做标志来对待。其中实体不会被展开。
三、DTD元素
在一个 DTD 中,元素通过元素声明来进行声明。
声明一个元素
元素声明语法:
<!ELEMENT element-name category>
或
<!ELEMENT element-name (element-content)>
空元素
空元素通过类别关键词EMPTY进行声明
<!ELEMENT element-name EMPTY> 实例: <!ELEMENT br EMPTY> XML example: <br />
只有PCDATA的元素
只有PCDATA的元素通过大括号中的#PCDATA进行声明:
<!ELEMENT element-name (#PCDATA)> 实例: <!ELEMENT from (#PCDATA)>
带有任何内容的元素
ANY 声明的元素,可包含任何可解析数据的组合:
<!ELEMENT element-name ANY> 实例: <!ELEMENT note ANY>
带有子元素(序列)的元素
带有一个或多个子元素的元素通过圆括号中的子元素名进行声明:
<!ELEMENT element-name (child1)> 或 <!ELEMENT element-name (child1,child2,...)> 实例: <!ELEMENT note (to,from,heading,body)>
当子元素按照由逗号分隔开的序列进行声明时,这些子元素必须按照相同的顺序出现在文档中。在一个完整的声明中,子元素也必须被声明,同时子元素也可拥有子元素。"note" 元素的完整声明是:
<!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)>
声明只出现一次的元素
<!ELEMENT element-name (child-name)> 实例: <!ELEMENT note (message)>
声明最少出现一次的元素
<!ELEMENT element-name (child-name+)> 实例: <!ELEMENT note (message+)>
声明才出现零次或多次的元素
<!ELEMENT element-name (child-name*)> 实例: <!ELEMENT note (message*)>
声明出现零次或一次的元素
<!ELEMENT element-name (child-name?)> 实例: <!ELEMENT note (message?)>
声明“非.../即...”类型的内容
实例: <!ELEMENT note (to,from,header,(message|body))>
声明混合型的内容
实例: <!ELEMENT note (#PCDATA|to|from|header|message)*>
上例声明了:"note" 元素可包含出现零次或多次的 PCDATA、"to"、"from"、"header" 或者 "message"。
四、DTD-属性
声明属性
属性声明使用下列语法
<!ATTLIST element-name attribute-name attribute-type attribute-value> DTD 实例: <!ATTLIST payment type CDATA "check"> XML 实例: <payment type="check" />
属性类型选型:
属性 描述
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 。
#REQUIRED
语法: <!ATTLIST element-name attribute-name attribute-type #REQUIRED> 实例: DTD: <!ATTLIST person number CDATA #REQUIRED> 合法的 XML: <person number="5677" /> 非法的 XML: <person />
#IMPLIED
语法: <!ATTLIST element-name attribute-name attribute-type #IMPLIED> DTD: <!ATTLIST contact fax CDATA #IMPLIED> 合法的 XML: <contact fax="555-667788" /> 合法的 XML: <contact />
#FIXED
语法: <!ATTLIST element-name attribute-name attribute-type #FIXED "value"> 实例: DTD: <!ATTLIST sender company CDATA #FIXED "Microsoft"> 合法的 XML: <sender company="Microsoft" /> 非法的 XML: <sender company="W3Schools" />
希望属性拥有固定的值,且不允许作者改变这个值。
列举属性值
语法: <!ATTLIST element-name attribute-name (en1|en2|..) default-value> 实例: DTD: <!ATTLIST payment type (check|cash) "cash"> XML 例子: <payment type="check" /> 或 <payment type="cash" />
希望属性值为一系列固定的合法值之一。使用列举属性值。
五、XML元素 vs. 属性
在XML中,并没有规定何时使用属性,以及何时使用子元素。
经验是:在 HTML 中多使用属性,但在XML中,使用子元素,会感觉更像数据信息。
较好的实践
<note date="12/11/2002"> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note>
如下:
<note> <date> <day>12</day> <month>11</month> <year>2002</year> </date> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note>
避免使用属性
一些属性具有以下问题:
属性不能包含多个值(子元素可以)
属性不容易扩展(为以后需求的变化)
属性无法描述结构(子元素可以)
属性更难以操纵程序代码
属性值是不容易测试,针对DTD
如果使用属性作为数据容器,最终的XML文档将难以阅读和维护。 尝试使用元素来描述数据。只有在提供的数据是不相关信息时才建议使用属性。
一个属性规则的例外
有时候在元素中应用了id属性,这些id应用在HTML中的很多相同的情况下课作为NAME或ID属性来访问XML元素。
<messages> <note id="p501"> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> <note id="p502"> <to>Jani</to> <from>Tove</from> <heading>Re: Reminder</heading> <body>I will not!</body> </note> </messages>
元数据(关于数据的数据)应当存储为属性,而数据本身应当存储为元素。
六、DTD-实体
实体是用于定义引用普通文本或特殊字符的快捷方式的变量。
实体引用是对实体的引用。
实体可在内部或外部进行声明。
一个内部实体声明
语法: <!ENTITY entity-name "entity-value"> 实例: DTD 实例: <!ENTITY writer "Donald Duck."> <!ENTITY copyright "Copyright runoob.com"> XML 实例: <author>&writer;©right;</author>
注意: 一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 (;)。
一个外部实体声明
语法: <!ENTITY entity-name SYSTEM "URI/URL"> DTD 实例: <!ENTITY writer SYSTEM "http://www.runoob.com/entities.dtd"> <!ENTITY copyright SYSTEM "http://www.runoob.com/entities.dtd"> XML example: <author>&writer;©right;</author>
七、DTD 验证
通过XML解析器进行验证
八、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"> ]>
XML Schema 用于定义 XML 文档的合法元素,类似 DTD。
XML Schema 是基于 XML 的 DTD 替代物。
与 DTD 不同,XML Schema 支持数据类型和命名空间。

浙公网安备 33010602011771号