420 likes | 576 Views
第 2 章 XML 文档类型定义. 由于 XML 可自定义标签,所以每个人定义的标签集都会不同,如果没有一套标准来规定标签的定义原则,则应用程序就不能对 XML 文档进行处理。解决该问题的方案采用 DTD , DTD(Document Type Definition ,文档类型定义 ) ,用于定义 XML 文档的编写规则。如哪些元素可出现在文档中,及元素的内容和属性的要求等。应用程序会利用这个 DTD 对文档进行检验,符合 DTD 约束规则的 XML 文档称之为有效文档,可以进行下一步处理,否则会报错,应用程序可捕获该错误进行相应的异常处理。检验过程是可选,这要视具体应用而定。.
E N D
第2章 XML文档类型定义 • 由于XML可自定义标签,所以每个人定义的标签集都会不同,如果没有一套标准来规定标签的定义原则,则应用程序就不能对XML文档进行处理。解决该问题的方案采用DTD,DTD(Document Type Definition,文档类型定义),用于定义XML文档的编写规则。如哪些元素可出现在文档中,及元素的内容和属性的要求等。应用程序会利用这个DTD对文档进行检验,符合DTD约束规则的XML文档称之为有效文档,可以进行下一步处理,否则会报错,应用程序可捕获该错误进行相应的异常处理。检验过程是可选,这要视具体应用而定。
第2章 XML文档类型定义 • 教学提示:XML的可扩展性表现在用户可以自己定义标记和标记之间的嵌套关系,而DTD就是进行这种定义的语言。它定义了文档的逻辑结构,规定了文档中所使用的元素、实体、元素的属性、元素与实体之间的关系。根据DTD可检查XML文档中的数据,以验证其是否符合规定和要求,这可以保证XML文档数据的正确性和有效性。本章介绍DTD的语法,包括元素、属性和实体的语法,结合例子给出DTD的使用方法并给出综合实例。 • 教学目标:了解DTD的作用,熟悉元素、属性及实体的运用,掌握引用DTD的方法,能够为特定的系统设计标记语言。
教学内容: • 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>Jims@163.com</email> <email>Jims@21cn.com</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>Jims@163.com</email> <email>Jims@21cn.com</email> </portal>
2.元素声明(参考:http://www.w3school.com.cn/dtd/dtd_elements.asp)2.元素声明(参考:http://www.w3school.com.cn/dtd/dtd_elements.asp) • 元素声明的格式为: <!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> <desc>dtd test</desc> <id>1</id> </name> 下面这个文档是有效的 <name> <id>1</id> <desc>dtd test</desc> </name>
下面的文档也是无效的,有多余的元素 <name> <id>1</id> <desc>dtd test</desc> <date>2005/01/31</date> </name>
子元素的个数,我们可通过正则表达式来规定子元素的个数。子元素的个数,我们可通过正则表达式来规定子元素的个数。 ?,允许零个或一个该元素 *,允许零个或多个该元素 +,允许一个或多个该元素
例如:下面我们可利用这些符号规定id子元素必须出现,且只能出现一次,而desc子元素可选。例如:下面我们可利用这些符号规定id子元素必须出现,且只能出现一次,而desc子元素可选。 <!ELEMENT name (id,desc*)>
根据上面的声明,下面的name元素都是有效的。根据上面的声明,下面的name元素都是有效的。 <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>
可选项(|),选项是一个参数列表,每个参数间用“|”分隔,代表能且只能选一个子元素。可选项(|),选项是一个参数列表,每个参数间用“|”分隔,代表能且只能选一个子元素。 <!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文档中添加元素,边添加边测试其正确性,这时可将尚未处理的部分作为字符数据组织到一个混合型元素中,以便使文档通过测试。但在文档最后完成时,要通过添加新元素的方法来清除这种非结构化信息。混合型元素的存在破坏了文档的层次结构化,不利于应用软件对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声明为一个元素声明多个属性,如: <!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名称记号。如: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属性可为元素分配一个唯一的标识符。ID类型的属性必须包含一个XML名称,而且该名称在文档中是独一无二的。ID属性可为元素分配一个唯一的标识符。 <!ATTLIST name card_id ID #REQUIRED> 由于数字不是合法的XML名称,所以ID编号不能以数字开头,解决办法是在前面加下划线或字母。
IDREF类型的属性指向文档中某元素的ID类型的属性。因此,它必须是一个XML名称,它的作用是当简单的包含关系不能满足要求时在元素间建立多对多关系。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中引用时,有以下几方面需注意。当内部一般实体在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元素里,格式如下:内部定义:内部的DTD定义必须定义在一个DOCTYPE元素里,格式如下: <!DOCTYPE root-element [element-declarations]>
外部定义:如果一个DTD定义在一个单独的DTD文件里,则XML文件引用定义DTD文件格式如下:外部定义:如果一个DTD定义在一个单独的DTD文件里,则XML文件引用定义DTD文件格式如下: <!DOCTYPE root-element SYSTEM "dtdfilename">
一个内部定义DTD的XML例子: <?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>
<?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来实现的。