DTD:定义XML文档的合法构建模块

本文详细介绍了DTD(文档类型定义),它是XML的一个重要组成部分,用于定义XML文档的合法构建模块。内容包括DTD的声明(内部与外部)、元素的声明格式和类别、属性的声明以及实体的定义。此外,还讲解了如何通过DTD验证XML文档,并提供了多个DTD实例,帮助读者深入理解其用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、简介

DTD:文档类型定义(Document Type Definition),可定义合法的XML文档构建模块。

DTD使用一系列合法的元素来定义文档的结构

DTD可被成行的声明在XML文档中,也可以作为一个外部引用

根据DTD即可写出符合DTD定义的XML文档

为什么使用 DTD?
1、通过 DTD,您的每一个 XML 文件均可携带一个有关其自身格式的描述。
2、通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据。
3、应用程序也可使用某个标准的 DTD 来验证从外部接收到的数据。
4、您还可以使用 DTD 来验证您自身的数据。

二、DTD声明

1、内部声明

**假如DTD被包含在XML源文件中,它应当通过下面的语法包装在
DOCTYPE声明中**

<!DOCTYPE root-element [element-declarations]>

实例:

<?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”
  • 第四行,第五行,第六行,第七行分别定义 to,from,heading,body 元素为 “#PCDATA” 类型

2、外部声明

**假如DTD被包含在XML源文件外,它应当通过下面的语法包装在
DOCTYPE声明中**

<!DOCTYPE root-element [element-declarations]>

实例:
xml文件

<?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)>

三、构建模块

所有XML以及HTML均有以下简单的模块构成

  • 元素:是XML和HTML文档的主要构建模块
  • 属性:提供有关属性的额外信息
  • 实体:用于定义引用普通文本或特殊字符( 等)的快捷方式的变量。
  • PCDATA:(parse character data)被解析的字符串。这些文本将被解析器检查实体以及标记。
  • CDATA:(character data)字符数据,不会被解析的文本(其中若包含标签,实体也不会被解析)

元素和属性:

<img src="computer.gif" />

img是元素,src是属性

元素和属性使用建议:

  • 数据可以在子元素或者属性中存储。
  • 通常情况下推荐在子元素在中存储。
  • 属性作为元素的唯一标识符,如id,name等,应在属性中存储
  • 元数据(描述数据的数据)应该在属性中存储,而数据的本身作为存储元素,如<messages><note name="description"><description>这是元数据</description></note></messages>

四、元素

1、元素的声明格式:

<!ELEMENT element-name category>

或者:

<!ELEMENT element-name (element-content)>

2、元素的类别:

(1). 空元素

通过关键字EMPTY声明:

<!ELEMENT element-name EMPTY>

实例:

<!ELEMENT br EMPTY>

XML example:

<br />
(2). 只有PCDATA的元素

通过圆括号中的PCDATA声明:

<!ELEMENT element-name (#PCDATA)>

实例:

<!ELEMENT from (#PCDATA)>
(3). 带有任何内容的元素

通过类别关键字ANY声明,可包含任何可解析数据的组合:

<!ELEMENT element-name ANY>

实例:

<!ELEMENT note ANY>
(4). 带有子元素(序列)的元素

带有一个或多个子元素的元素通过圆括号中的子元素名进行声明:

<!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)>
(5). 声明只出现一次的元素
<!ELEMENT element-name (child-name)>

实例:

<!ELEMENT note (message)>
声明了message 子元素必须出现一次,并且必须只在 "note" 元素中出现一次。
(6). 声明最少出现一次的元素

在子元素名后跟上”+“号:

<!ELEMENT element-name (child-name+)>

实例:

<!ELEMENT note (message+)>
(7). 声明出现0次或者1次的元素

在子元素名后跟上”*”号:

<!ELEMENT element-name (child-name*)>

实例:

<!ELEMENT note (message*)>
(8). 声明”非…既…”类型的内容

在元素之间使用”|“号:

<!ELEMENT element-name (child1,child2,(child3|child4),child5)>

实例:

<!ELEMENT note (to,from,header,(message|body))>
(9). 声明混合型内容

实例:

<!ELEMENT note (#PCDATA|to|from|header|message)*>

上面的例子声明了:”note” 元素可包含出现零次或多次的 PCDATA、”to”、”from”、”header” 或者 “message”。

五、属性

1、属性通过ATTLIST进行声明,语法

<!ATTLIST element-name attribute-name attribute-type attribute-value>

2、属性类型

类型描述
CDATA值为字符数据 (character data)
(枚举列表:值用竖线隔开)此值是枚举列表中的一个值
ID值为唯一的 id
IDREF值为另外一个元素的 id
IDREFS值为其他 id 的列表
NMTOKEN值为合法的 XML 名称
NMTOKENS值为合法的 XML 名称的列表
ENTITY值是一个实体
ENTITIES值是一个实体列表
NOTATION此值是符号的名称
xml:值是一个预定义的 XML 值

3、默认属性值

解释
#REQUIRED属性值是必需的
#IMPLIED属性不是必需的
#FIXED value属性值是固定的

4、列举属性值

如果您希望属性值为一系列固定的合法值之一,请使用列举属性值。语法:

<!ATTLIST element-name attribute-name (en1|en2|..) default-value>

实例:

DTD:
<!ATTLIST payment type (check|cash) "cash">

XML 例子:
<payment type="check" /><payment type="cash" />

六、实体

实体是用于定义引用普通文本或特殊字符的快捷方式的变量。

  • 实体引用是对实体的引用。
  • 实体可在内部或外部进行声明。
    注意:一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 (;)。

1、内部实体声明

语法:

<!ENTITY entity-name "entity-value">

DTD实例:

<!ENTITY writer "Donald Duck.">
<!ENTITY copyright "Copyright W3CSchool.cc">

XML 实例:

<author>&writer;&copyright;</author>

2、外部实体声明

语法:

<!ENTITY entity-name SYSTEM "URI/URL">

DTD 实例:

<!ENTITY writer SYSTEM "http://www.w3cschool.cc/entities.dtd">
<!ENTITY copyright SYSTEM "http://www.w3cschool.cc/entities.dtd">

XML 实例:

<author>&writer;&copyright;</author>

七、DTD验证XML

**使用 Internet Explorer 可根据某个 DTD 来验证您的 XML。

1、通过XML解析器进行验证

当您试图打开某个 XML 文档时,XML 解析器有可能会产生错误。通过访问 parseError 对象,就可以取回引起错误的确切代码、文本甚至所在的行。

注意: load() 方法用于文件,而 loadXML() 方法用于字符串。

实例:

var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async="false";
xmlDoc.validateOnParse="true";
xmlDoc.load("note_dtd_error.xml");

document.write("<br />Error Code: ");
document.write(xmlDoc.parseError.errorCode);
document.write("<br />Error Reason: ");
document.write(xmlDoc.parseError.reason);
document.write("<br />Error Line: ");
document.write(xmlDoc.parseError.line);

2、关闭验证

通过把 XML 解析器的 validateOnParse 设置为 “false”,就可以关闭验证。

xmlDoc.validateOnParse="false";

3、通用的XML验证器

八、DTD实例演示

根据DTD即可写出对应的XML文档

1. 电视节目表 DTD

<!DOCTYPE TVSCHEDULE [
<!--根元素为:TVSCHEDULE-->
<!ELEMENT TVSCHEDULE (CHANNEL+)>
<!--TVSCHEDULE的子元素CHANNEL至少出现1次-->
<!ELEMENT CHANNEL (BANNER,DAY+)>
<!--CHANNEL的子元素BANNER出现1次,DAY至少出现1次-->
<!ELEMENT BANNER (#PCDATA)>
<!--BANNER元素为PCDATA类型-->
<!ELEMENT DAY (DATE,(HOLIDAY|PROGRAMSLOT+)+)>
<!--DAY元素的不是子元素HOLIDAY出现1次,就是PROGRAMSLOT出现至少1次-->
<!ELEMENT HOLIDAY (#PCDATA)>
<!--HOLIDAY元素为PCDATA类型-->
<!ELEMENT DATE (#PCDATA)>
<!--DATE元素为PCDATA类型-->
<!ELEMENT PROGRAMSLOT (TIME,TITLE,DESCRIPTION?)>
<!--PROGRAMSLOT的子元素TIME(1次),TITLE(1次),DESCRIPTION(可能出现)-->
<!ELEMENT TIME (#PCDATA)>
<!--TIME元素为PCDATA类型-->
<!ELEMENT TITLE (#PCDATA)> 
<!--TITLE元素为PCDATA类型-->
<!ELEMENT DESCRIPTION (#PCDATA)>
<!--DESCRIPTION元素为PCDATA类型-->
<!ATTLIST TVSCHEDULE NAME CDATA #REQUIRED>
<!--TVSCHEDULE的属性name的值必填且为字符-->
<!ATTLIST CHANNEL CHAN CDATA #REQUIRED>
<!--CHANNEL的属性CHAN的值必填且为字符-->
<!ATTLIST PROGRAMSLOT VTR CDATA #IMPLIED>
<!--PROGRAMSLOT的属性VTR的值可填可不填,填的值为字符-->
<!ATTLIST TITLE RATING CDATA #IMPLIED>
<!--TITLE的属性RATING的值可填可不填,填的值为字符-->
<!ATTLIST TITLE LANGUAGE CDATA #IMPLIED>
<!--TITLE的属性LANGUAGE的值可填可不填,填的值为字符-->
]>

2. 报纸文章 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">

]>

3. 产品目录 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)>

]>

参考教程:http://www.runoob.com/dtd/dtd-attributes.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值