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 实体引用:"&nbsp;"。这个"无折行空格"实体在 HTML 中被用于在某个文档中插入一个额外的空格。
实体引用   字符
&lt;      <
&gt;        >
&amp;      &
&quot;       "
&apos;      '

PCDATA
PCDATA (parsed character data) -->被解析的字符数据。
可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本.
PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。
文本中的标签会被当作标记来处理,而实体会被展开。
不过,被解析的字符数据不应当包含任何 &、< 或者 > 字符;需要使用 &amp;、&lt; 以及 &gt; 实体来分别替换它们

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>
View Code

元数据(关于数据的数据)应当存储为属性,而数据本身应当存储为元素。

六、DTD-实体
实体是用于定义引用普通文本或特殊字符的快捷方式的变量。
  实体引用是对实体的引用。
  实体可在内部或外部进行声明。

一个内部实体声明

语法:
<!ENTITY entity-name "entity-value">
实例:
DTD 实例:
<!ENTITY writer "Donald Duck.">
<!ENTITY copyright "Copyright runoob.com">
XML 实例:
<author>&writer;&copyright;</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;&copyright;</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">

]>
View Code


XML Schema 用于定义 XML 文档的合法元素,类似 DTD。
XML Schema 是基于 XML 的 DTD 替代物。
与 DTD 不同,XML Schema 支持数据类型和命名空间。


posted @ 2018-12-24 22:25  payn  阅读(216)  评论(0)    收藏  举报