|
|
|
[XML初学进阶]XML(35)合并 网上资源
|
|
3.1.2.8 混合内容
当然,可能也有一些时候,你在一个元素中既希望包含子元素,也希望包含纯文本。XML中允许这种使用方法,并把这种元素称为混合内容的元素。在下面的例子中,“联系人”就是一个混合元素。
<?xml version = "1.0" encoding="GB2312" standalone = "yes"?><!DOCTYPE CONTACTS [ <!ELEMENT 联系人列表 ANY> <!ELEMENT 联系人(姓名|电话|EMAIL|#PCDATA)*> <!ELEMENT 姓名(#PCDATA)> <!ELEMENT 电话(#PCDATA)> <!ELEMENT EMAIL(#PCDATA)> ]>
<联系人列表> <联系人> <姓名>张三</姓名> <电话>(010)62345678</电话> <EMAIL>zhang@aaa.com</EMAIL> 这是关于张三的信息 </联系人></联系人列表>
注意,由于在“(姓名|电话|EMAIL|#PCDATA)”之外有“*”,所以在元素“联系人”中可以包含零个或多个“姓名”、电话、EMAIL和纯文本字段。
3.1.2.9 空元素
好了,前面我们已经介绍了所有可能用到的子元素的排列状况。不过,还有一种情况没有说,那就是,一个元素中不包含任何子元素,也不包含纯文本。
对于这种情况,我们可以定义一个空标记。当然,定义这样一个标记很简单,你只需要使用关键字EMPTY就可以了,例如:
<!ELEMENT HR EMPTY>
这样,在你的XML文件中,就可以使用一个空元素<HR/>。
3.1.3.1 定义有效的元素属性
好了,上面我们用了很大的篇幅来讲ETD的定义,现在我们已经学会如何定义一个元素以及它的内容,如何描述父元素与子元素之间错综复杂的关系,只差不知道如何定义元素的属性了。
在第二章中我们曾经提到过属性,那个例子是一个有关“商品”的元素,它有两个属性,即“类型”和“颜色”:
<商品 类型 = "服装" 颜色 = "黄色">
在DTD中定义属性时,我们使用下面的格式:
<!ATTLIST 元素名 (属性名 属性类型 缺省值)*>
元素名是属性所属的元素的名字,在上面例子中,元素名是“商品”;属性名是属性的命名,例子中,“类型”和“颜色”是属性名;缺省值说明在XML文件中,如果没有特别说明属性的取值,语法分析器默认它具有的取值;属性类型则用来指定该属性是属于十个有效属性类型中的哪种类型。
注意:由于ATTLIST是一个属性的列表,它可以包含很多属性,在实际应用中,一个元素也经常有多个属性。
上面例子中的属性可以如下定义:
<!ATTLIST 商品 类型 CDATA #REQUIRED 颜色 CDATA #IMPLIED>
在元素说明的四个部分中,我们需要再详细讨论一下元素类型和缺省值。在下一节中,我们就从缺省值说起。
3.1.3.2 属性缺省值
根据XML文件是否必须为一个属性提供取值,属性的缺省值又可以分为以下三类:
必须赋值的属性关键字REQUIRED说明XML文件中必须为这个属性给出一个属性值。例如,假设你想定义一个"页面作者"元素,并把这个元素加入所有网站中的每一个页面。之所以定义这个元素,是为了页面编辑者能够提供他的联系信息,以便当发现页面错误或无效链接时,可以及时地通知他。在这种情况下,每个页面作者都有不同的个人信息,所以你无法事先知道应该用什么作为缺省值,但你又的确需要提供每个人的信息。这时候,你就可以把与联系信息相关的属性定义为必须的(REQUIRED),而且不用提供缺省值。
属性值可有可无的属性当使用IMPLIED关键字时,文法解释器不再强行要求你在XML文件中给该属性赋值,而且也无须在DTD中为该属性提供缺省值。可以说,这是对属性值有无的最低要求,现实中经常用到。
固定取值的属性还有一种特殊情况,你需要为一个特定的属性提供一个缺省值,并且不希望XML文件的编写者把你的缺省值替代掉。这时候,就应该使用FIXED关键字,同时为该属性提供一个缺省值。
定义缺省值的属性如果不使用上面任何一种关键字的话,该种属性就是属于这种类型。对于这种属性,你需要在DTD中为它提供一个缺省值。而在XML文件中可以为该属性给出新的属性值来覆盖事先定义的缺省值,也可以不另外给出属性值,后一种情况下它就默认为采用DTD中给出的缺省值。
至于究竟采用哪种缺省值,就看实际需要了。下面给出一个具体的例子:
<!ATTLIST 页面作者 姓名 #CDATA #IMPLIED 年龄 #CDATA #IMPLIED 联系信息 #CDATA #REQUIRED 网站职务 #CDATA #FIXED "页面作者" 个人爱好 #CDATA "上网">
3.1.3.3 属性类型
一个元素可以为以下十种类型中的任意一种:
CDATA
Enumerated
ID
IDREF
IDREFS
ENTITY
ENTITIES
NMTOKEN
NMTOKENS
NOTATION
下面我们就来一个一个讲述。
.1.3.4 CDATA类型
CDATA指的是纯文本,即由字符、符号“&”、小于号“<”和引号“"”组成的字符串。当然,就象我们前面讲到的,你应该使用实体&代替“&”,<代替“<”,"代替“"”。
请看下面这个关于剧本的例子:
<?xml version = "1.0" encoding="GB2312" standalone = "yes"?><!DOCTYPE 剧本 [ <!ELEMENT 剧本 ANY> <!ELEMENT 对话 (#PCDATA)> <!ATTLIST 对话 演员 CDATA> ]>
<剧本> <对话 演员="某甲">我可不这么认为!</对话> <对话 演员="某乙">为什么呢?</对话></剧本>
3.1.3.5 枚举类型
属性也可以被描述为一组可接受的取值的列表,XML文件中对属性的赋值将从这个列表中选取一个值。这类属性属于枚举类型ENUMERATED,不过,关键字ENUMERATED是不出现在DTD定义中的。
<?xml version = "1.0" encoding="GB2312" standalone = "yes"?><!DOCTYPE 购物篮 [ <!ELEMENT 购物篮 ANY> <!ELEMENT 肉 EMPTY> <!ATTLIST 肉 类型( 鸡肉 | 牛肉 | 猪肉 | 鱼肉 ) "鸡肉"> ]>
<购物篮> <肉 类型 = "鱼肉"/> <肉 类型 = "牛肉"/> <肉/></购物篮>
注意,在上面这个例子中,给属性“类型”定义的缺省值是“鸡肉”,所以“购物篮”中的第三个元素的“类型”属性取值为“鸡肉”。
3.1.3.6 ID和IDREF
ID类型
ID是用属性值的方式为文件中的某个元素定义唯一标识的方法,它的作用类似于HTML文件中的内部链接。在大多数情况下,ID由处理文件的程序或脚本语言使用。
ID的值必须是一个有效的XML名称,它由字母、数字或下划线开始,名字中不能出现空白符。另外一般而言,不要给ID类型的属性事先指定缺省值,这很容易引起不同的元素具有相同的标识的情况,更不能使用FIXED型的缺省值。此类属性经常使用REQUIRED缺省类型,当然,这也不是必须的。有的应用并不要求每个元素都有自己的标识,所以,也可以使用IMPLIED缺省类型。
<?xml version = "1.0" encoding="GB2312" standalone = "yes"?><!DOCTYPE 联系人列表[ <!ELEMENT 联系人列表 ANY> <!ELEMENT 联系人(姓名,EMAIL)> <!ELEMENT 姓名(#PCDATA)> <!ELEMENT EMAIL(#PCDATA)> <!ATTLIST 联系人 编号 ID #REQUIRED> ]><联系人列表> <联系人 编号="1"> <姓名>张三</姓名> <EMAIL>zhang@aaa.com</EMAIL> </联系人> <联系人 编号="2"> <姓名>李四</姓名> <EMAIL>li@bbb.org</EMAIL> </联系人></联系人列表>
IDREF类型
IDREF类型允许一个元素的属性使用文件中的另一个元素,方法就是把那个元素的ID标识值作为该属性的取值。例如下面的例子:
<?xml version = "1.0" encoding="GB2312" standalone = "yes"?><!DOCTYPE 联系人列表[ <!ELEMENT 联系人列表 ANY> <!ELEMENT 联系人(姓名,EMAIL)> <!ELEMENT 姓名(#PCDATA)> <!ELEMENT EMAIL(#PCDATA)> <!ATTLIST 联系人 编号 ID #REQUIRED> <!ATTLIST 联系人 上司 IDREF #IMPLIED> ]><联系人列表> <联系人 编号="2"> <姓名>张三</姓名> <EMAIL>zhang@aaa.com</EMAIL> </联系人> <联系人 编号="1" 上司="2"> <姓名>李四</姓名> <EMAIL>li@aaa.com</EMAIL> </联系人></联系人列表>
3.1.3.7 NMTOKEN和NMTOKENS
类型NMTOKEN和NMTOKENS是诸多属性类型中面向处理程序的又一个类型。这两个类型用于指示一个有效的名字。当需要把一个元素和其它的元件,例如一个JAVA类或一个安全算法,相联系时,可以让它们助你一臂之力。请看下面的例子:
关于元素的定义:
<!ELEMENT 数据(#PCDATA)><!ATTLIST 数据 安全性( ON | OFF ) "OFF"> 授权用户 NMTOKENS #IMPLIED>
XML文件:
<数据 安全性="ON" 授权用户 = "IggieeB SelenaS GuntherB">blah blah blah</数据>
3.1.3.8 NOTATION类型
NOTATION类型允许属性值为一个DTD中声明的符号,这个类型对于使用非XML格式的数据非常有用。
现实世界中存在着很多无法或不易用XML格式组织的数据,例如图象、声音、影象等等。对于这些数据,XML应用程序常常并不提供直接的应用支持。通过为它们设定NOTATION类型的属性,可以向应用程序指定一个外部的处理程序。例如,当你想要为一个给定的文件类型指定一个演示设备时,可以用NOTATION类型的属性作为触发。
要使用NOTATION类型作为属性的类型,首先要在DTD中为可选用的记号作出定义。定义的方式有两种,一种是使用MIME类型,形式是:
<!NOTATION 记号名 SYSTEM "MIME类型">
再有一种是使用一个URL路径,指定一个处理程序的路径。
<!NOTATION 记号名 SYSTEM "URL路径名">
在下面这个例子中,为"电影"元素指定了两种可选设备:一种是movPlayer.exe,用来播映.mov文件,另一种则用来绘制GIF图象。
<?xml version = "1.0" encoding="GB2312" standalone = "yes"?><!DOCTYPE 文件[ <!ELEMENT 文件 ANY> <!ELEMENT 电影 EMPTY> <!ATTLIST 电影 演示设备 NOTATION ( mp | gif ) #REQUIRED> <!NOTATION mp SYSTEM "movPlayer.exe"> <!NOTATION gif SYSTEM "Image/gif"> ]><文件> <电影 演示设备 = "mp"/></文件>
3.1.3.9 实体属性类型与参数实体
在上一章中,我们介绍过实体的概念。相信你还能回忆起来,实体在XML中充当着宏或别名的角色。
实体最根本的作用是帮助你为一大段文本创建一个别名,这样,在文件的另一个位置需要引用这段文本时,仅需要指向它的别名就可以了。可想而知,这样一来,用于重新输入这段文本的大量时间就被节约下来了。它还意味着一旦需要修改,仅需要在一个地方作改动,就完成了全局的改动。
我们还提到,实体分为一般实体和参数实体两种类型,它们都可以定义为内部的也可以用关键字SYSTEM定义为外部的。实体的定义必须出现在引用之前,而且要注意正确嵌套,不能出现循环引用的情况。在DTD中,这两种类型的实体都得到了广泛的应用。
实体属性类型
实体类型的属性值属于一般实体,如前所述,它的定义方式是:
<!ENTITY 实体名 "实体内容">
或利用SYSTEM定义外部实体,方式为:
<!ENTITY 实体名 SYSTEM "外部文件名">
引用方式为:
&实体名;
使用关键字ENTITY,则声明一个属性是实体类型,它的取值为已定义的实体。请看下面例子:
<?xml version = "1.0" encoding="GB2312" standalone = "yes"?><!DOCTYPE 文件[ <!ELEMENT 文件 ANY> <!ELEMENT 电影 EMPTY> <!ATTLIST 电影 来源 ENTITY #REQUIRED> <!ENTITY BladeRunner SYSTEM "dvds/BR/br.mov"> ]><文件> <电影 来源 = "&BladeRunner;"></文件>
参数实体
参数实体专门用在DTD中。定义方式是:
<!ENTITY % 实体名 "实体内容">
或:
<!ENTITY % 实体名 SYSTEM "外部文件名">
引用方式为:
%实体名;
使用参数实体,可以方便元素和属性的声明。例如:
<!ENTITY % TAG_NAMES "姓名 | EMAIL | 电话 | 地址"><!ELEMENT 个人联系信息 (%TAG_NAMES; | 生日)><!ELEMENT 客户联系信息 (%TAG_NAMES; | 公司名)>
最后提醒大家注意,不要以为实体属性类型的定义与DTD有关,所以它使用的就是参数实体。参数实体只能在DTD中使用,而对于任何元素属性值的指定(除了缺省值外),都是在XML文件正文中进行的,因此实体属性值仍属于一般实体。
| |
|
|
|