第 2 章 xml 文档类型定义
DESCRIPTION
第 2 章 XML 文档类型定义. 由于 XML 可自定义标签,所以每个人定义的标签集都会不同,如果没有一套标准来规定标签的定义原则,则应用程序就不能对 XML 文档进行处理。解决该问题的方案采用 DTD , DTD(Document Type Definition ,文档类型定义 ) ,用于定义 XML 文档的编写规则。如哪些元素可出现在文档中,及元素的内容和属性的要求等。应用程序会利用这个 DTD 对文档进行检验,符合 DTD 约束规则的 XML 文档称之为有效文档,可以进行下一步处理,否则会报错,应用程序可捕获该错误进行相应的异常处理。检验过程是可选,这要视具体应用而定。. - PowerPoint PPT PresentationTRANSCRIPT
由于 XML 可自定义标签,所以每个人定义的标签集都会不同,如果没有一套标准来规定标签的定义原则,则应用程序就不能对 XML 文档进行处理。解决该问题的方案采用 DTD , DTD(Document Type Definition,文档类型定义 ) ,用于定义 XML 文档的编写规则。如哪些元素可出现在文档中,及元素的内容和属性的要求等。应用程序会利用这个 DTD 对文档进行检验,符合 DTD 约束规则的 XML 文档称之为有效文档,可以进行下一步处理,否则会报错,应用程序可捕获该错误进行相应的异常处理。检验过程是可选,这要视具体应用而定。
第 2 章 XML 文档类型定义
教学提示: XML 的可扩展性表现在用户可以自己定义标记和标记之间的嵌套关系,而 DTD 就是进行这种定义的语言。它定义了文档的逻辑结构,规定了文档中所使用的元素、实体、元素的属性、元素与实体之间的关系。根据 DTD 可检查 XML 文档中的数据,以验证其是否符合规定和要求,这可以保证 XML 文档数据的正确性和有效性。本章介绍 DTD 的语法,包括元素、属性和实体的语法,结合例子给出 DTD 的使用方法并给出综合实例。
教学目标:了解 DTD 的作用,熟悉元素、属性及实体的运用,掌握引用 DTD 的方法,能够为特定的系统设计标记语言。
第 2 章 XML 文档类型定义
教学内容:
1. 文档类型声明 2. 元素声明 3. 属性声明
3.1. 属性类型 3.2. 属性缺省值
4. 实体
1 文档类型声明( 参考: http://www.w3school.com.cn/dtd/dtd_intro.asp )
要使用 DTD 进行有效性检验,就要使用文档类型定义声明指定 DTD 。如:
<?xml version="1.0" standalone="no"?> <!DOCTYPE portal SYSTEM "http://www.w3c.com/dtd/portal.dtd"> <portal>
<name>Jims</name> <email>[email protected]</email> <email>[email protected]</email> </portal>
上面的例子是引用了外部的DTD 。
文档类型声明位于 XML 声明之后,根元素之前。如果 dtd 文档位于本机,可用路径名直接指出 dtd文档的位置。
那么这个 portal.dtd 的内容是什么呢?
portal.dtd 的内容如下:
<!ELEMENT portal (name,email*)><!ELEMENT name (#PCDATA)><!ELEMENT email (#PCDATA)>
上面的内容也可直接写到 XML 文档内。
<?xml version="1.0“ standalone="no"?> <!DOCTYPE portal [
<!ELEMENT portal (name,email*)> <!ELEMENT name (#PCDATA)> <!ELEMENT email (#PCDATA)> ]> <portal>
<name>Jims</name> <email>[email protected]</email> <email>[email protected]</email> </portal>
2. 元素声明(参考: http://www.w3school.com.cn/dtd/dtd_elements.as
p )
元素声明的格式为:<!ELEMENT element_name (content_model)> 有效文档中使用的每个元素都必须在文档的 DTD 中用
元素声明进行声明。 element_name 可是任何合法的 XML 名称, content_model( 内容模型 ) 指定元素可以或必须包含的子元素以及子元素的顺序。
下面介绍内容模型的内容。
内容模型 #PCDATA ,规定元素只包含已析的字符数据。下面声明指
出一个 name 元素可以包含文本,但不能划分为独立的area_code 、 number 和 extension 元素:
<!ELEMENT name (#PCDATA)> 子元素,可指明元素的子元素。下面声明表示 name 元素必
须包含且只包含一个 desc 元素。
<!ELEMENT name (desc)>也可用逗号为分隔符,指明多个子元素。并且子元素出现的次序
必须按定义时的顺序。如:
<!ELEMENT name (id,desc)>name 元素的 id 子元素必须在 desc 子元素前面,否则验证会出
错,该文档不是一个有效的 XML 文档。
下面这个文档是有效的 <name> <id>1</id> <desc>dtd test</desc> </name>
下面这个文档是无效的,顺序颠倒了
<name> <desc>dtd test</desc> <id>1</id></name>
下面的文档也是无效的,有多余的元素 <name> <id>1</id> <desc>dtd test</desc>
<date>2005/01/31</date> </name>
子元素的个数,我们可通过正则表达式来规定子元素的个数。
? ,允许零个或一个该元素
* ,允许零个或多个该元素
+ ,允许一个或多个该元素
例如:下面我们可利用这些符号规定 id 子元素必须出现,且只能出现一次,而desc 子元素可选。
<!ELEMENT name (id , desc*)>
<name> <id>1</id> <desc>dtd test</desc> </name>
<name> <id>2</id> </name>
<name> <id>3</id> <desc>dtd test</desc> <desc>another test</desc> </name>
根据上面的声明,下面的 name元素都是有效的。
可选项 (|) ,选项是一个参数列表,每个参数间用“ |” 分隔,代表能且只能选一个子元素。
<!ELEMENT choice (good | bad)> 上例的 choice 元素可选一个 good 子元素,或 bad
子元素,且只能从选一个。可选的参数列可以多项,不限于两项。如:
<!ELEMENT choice (one | two | three | four)>
混合内容:在一些文档中,一个元素可能既包含子元素,也包含字符串,这些内容叫混合内容。
<!EMEMENT description (#PCDATA | term)* )>该声明表示 description 元素可包含已析的字符串和
term 子元素,且允许出现零次或多次,如:
<description>this is a <term>dtd</term> test.</description>#PCDATA 必须在第一位,可选的子元素可任意多项。
混合型元素的存在破坏了文档的层次结构化,不利于应用软件对 XML 文档的处理,在 XML 文档开发过程中,它可以作为一个不成熟的 DTD 文档,一步一步地在 XML 文档中添加元素,边添加边测试其正确性,这时可将尚未处理的部分作为字符数据组织到一个混合型元素中,以便使文档通过测试。但在文档最后完成时,要通过添加新元素的方法来清除这种非结构化信息。
空元素
某些元素不用包含任何内容,称之为空元素。写成以 /> 结束的独立标签。
<!ELEMENT image EMPTY> 示例:<image src="http://www.xml.com/dtd.jpg" />
ANY
允许元素内包含任意内容。该选项在 dtd测试时很有用,在生产系统中尽量不要使用。
<!ELEMENT page ANY>
3 属性声明 ( 参考: http://www.w3school.com.cn/dtd/dtd_attributes.asp )
<!ATTLIST image src CDATA #REQUIRED>该例声明 image 元素必须有一个 src 属性,该属性的值是
字符数据。
可用 ATTLIST 声明为一个元素声明多个属性,如:
<!ATTLIST image src CDATA #REQUIRED width CDATA #REQUIRED height CDATA #REQUIRED alt CDATA #IMPLIED>上述声明指出 src 、 width 、 height 属性是必须的,
alt 属性是可选的。
3.1 属性的类型
CDATA 类型属性值可包含任意文本字符串。 DTD 不能指定属性为一个整数或一个日期, Schema 能提供更为强大的数据类型。
NMTOKEN 类型属性值是一个 XML 名称记号。 XML 名称记号与 XML 名称类似,但 XML 名称记号允许所有的字符作为名称的开始字符,而 XML 名称的第一个字母必须是字母、表意字符和下划线。因此 10 , .bashrc 是合法的XML 名称标记,但不是合法的 XML 名称。每个 XML 名称都是一个 XML 名称标记,然而 XML 名称标记不全是 XML名称。如果属性包含 1990 , 2005 之类的整数,则应该指定其类型为 NMTOKEN 。如:
<!ELEMENT person birthday NMTOKEN #REQUIRED>
NMTOKENS 类型属性包含一个或多个用空白分隔的 XML名称记号。如:
<person dates="02-01-2005 03-01-2005 05-01-2005">person</person>
对应的声明应为:<!ATTLIST person dates NMTOKENS #REQUIRED>
枚举声明:枚举不用关键字。直接列举所有的值,中间用竖线分隔。如:
<!ATTLIST date month(January | February | March | April | May | June | July | August | September | October | November | December) #REQUIRED>
针对上述声明, date 元素的 month 属性可选十二个月份的中一个。
ID 类型的属性必须包含一个 XML 名称,而且该名称在文档中是独一无二的。 ID 属性可为元素分配一个唯一的标识符。
<!ATTLIST name card_id ID #REQUIRED>
由于数字不是合法的 XML 名称,所以 ID 编号不能以数字开头,解决办法是在前面加下划线或字母。
IDREF 类型的属性指向文档中某元素的 ID 类型的属性。因此,它必须是一个 XML 名称,它的作用是当简单的包含关系不能满足要求时在元素间建立多对多关系。
NOTATION 类型
<!ATTLIST Image type NOTATION (gif|jpg) "gif">
<Image type="jpg">...
在以上声明中, Image 元素可以有一个名为 type的属性,它是表示法类型的。该属性可选的值有gif 和 jpg 。如果元素实例没有定义 type 属性,解析器会假设该属性设置为缺省值 gif 。然而,在上述实例中,值 jpg覆盖了缺省值。
3.2 实体 ( 参考: http://www.w3school.com.cn/dtd/dtd_entities.asp) ( 1 )按照实体的具体内容来分类,实体可分为可解析与不可解
析两类。可解析实体的具体内容为简单的字符、数字、文本块,而不可解析实体的具体内容则为图片、声音等二进制文件。
( 2 )按照逻辑存储来分类,实体可分为内部实体与外部实体两类。内部实体的内容是在文档内部设定的;而外部实体则是一个外部独立的物理存储对象,如某个外部文件。
( 3 )按照使用的范围来分类,实体可分为一般实体与参数实体两类。一般实体都用来构成文档的具体内容,可出现在 XML文档中,也可出现在 DTD 中;而参数实体只能出现在 DTD中,不能出现在 XML 文档中。
1. 内部一般实体 内部一般实体就是在文档实体内部定义和使用的实体,其内容
通常是一段文本字符。这种实体要在 DTD 中通过 DTD 语句的定义,可以在 XML 文档中使用,也可在 DTD 中使用。其定义的语法格式如下:
<!ENTITY Eentity_name "Replacement" > 其中, <!ENTITY> 为关键字, Eentity_name 为实体名称,
Replacement 为实体所代替的文本内容。引用内部一般实体的方法如下:
&Eentity_name;
当内部一般实体在 DTD 中引用时,有以下几方面需注意。(1) 不能在元素及属性的声明中引用内部一般实体,如下面的语句即为非法的:
<!ENTITY pcd (#PCDATA)><!ELEMENT title &pcd;>
(2) 在语句中不能出现循环,如下面的语句即为非法的:<!ENTITY thepub "北大 &pub;"><!ENTITY pub " 出版社 &thepub;">
2. 外部一般实体 所谓外部一般实体就是在文档实体以外定义的,要通过一个
URL才能引用到的实体。外部一般实体为独立的文件,可被多个文档所引用。正因为每一个完整的 XML 文档都是一个合法的实体,所以 XML 通过对外部一般实体的引用,可以在一个 XML 文档中嵌入另一个 XML 文档,或者将多个文档组合成一个文档。其定义的语法格式如下:
<!ENTITY Eentity_name "URL" > 其中, URL 为引用的外部实体的 URL地址。引用外部一般实
体也与引用内部一般实体的方法一样: &Eentity_name;
在引用外部一般实体时,有以下几方面需注意。(1) 因为在一个文档中需引用某些外部文件,所以该文档声明中
的 standalone 属性不再是默认值 yes ,而应该为 no 。(2) 作为外部一般实体的文档,若使用的是 XML 的默认字符集
即 UTF-8 或 UNICODE ,则可以在文档头部不进行 XML 声明,否则,必须有 XML 声明,且声明时,一定要说明ecoding 属性。
3. 内部参数实体 内部参数实体是指在独立的外部 DTD 文档的内部定义和使用
的实体,其内容为仅能为 DTD 而非 XML 文档内容的书写文本。这里提到参数实体与前面所讲的一般实体是有区别的:
(1) 在引用形式上,一般实体的引用为“ &Eentity_name;”,而参数实体的引用则为“ %Eentity_name;”
(2) 在引用范围上,一般实体可在 XML 文档中引用,也可在DTD 中引用,而参数实体只可在 DTD 中引用。
定义内部参数实体的语法格式如下: <!ENTITY % Eentity_name "Replacement" >
4. 外部参数实体 外部参数实体是指在独立的外部 DTD 文档的外部定义和使用
的实体,外部参数实体用于将多个独立的 DTD 文档组合成一个大的 DTD 文档。定义外部参数实体的语法格式如下:
<!ENTITY % Eentity_name "URL" >
3.2. 属性缺省值
每个 ATTLIST 声明除了要提供一种数据类型外,还要声明属性的缺省行为。 #IMPLIED ,属性可选。
#REQUIRED ,属性必须有。
#FIXED ,属性是常量,不能更改。 <!ATTLIST person name CDATA #FIXED "linuxsir“>
Literal ,作为一个引用字符串的实际缺省值。 <!ATTLIST person name NMTOKEN "linuxsir“> 如果没有显示指明 person 元素的 name 属性,则该值为
linuxsir 。
4 使用 DTD
DTD 可以定义在 XML里,也可以定义在一个单独的文件里。
内部定义:内部的 DTD 定义必须定义在一个 DOCTYPE 元素里,格式如下:
<!DOCTYPE root-element [element-declarations]>
外部定义:如果一个 DTD 定义在一个单独的 DTD 文件里,则 XML 文件引用定义 DTD 文件格式如下:
<!DOCTYPE root-element SYSTEM "dtdfilename">
<?xml version="1.0"?><!-- Edited by XMLSpy? --><!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 的 XML 例子:
<?xml version="1.0"?><!-- Edited by XMLSpy? --><!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 ,即为内部 DTD 与外部 DTD 混
合使用。在 DTD 使用的实际情况中, 很少使用完全标准的 DTD ,往往是公司先为所有的开发小组提供一分公共的 DTD 作为外部 DTD ,然后各个成员在实际的使用过程中再进行扩展定义,这时的扩展定义常常是使用内部 DTD 来实现的。
谢谢谢谢