DTD是Document Type Definition(文档类型定义)的缩写。它通过定义元素、属性、标记以及文档中的实体及其相互关系等规则来保证XML文档的合法性。
1.DTD的声明方式分为内部声明与外部声明
内部声明的格式是
DOCTYPE 根元素 [
ELEMENT 根元素 (元素1,元素2)
>
ELEMENT 元素1 (#PCDATA)
>
ELEMENT 元素2 (#PCDATA)
>
]>
外部声明的格式分两种,对应的关键字为"SYSTEM"与"PUBLIC"
DOCTYPE 根元素 SYSTEM "外部DTD文件"
>
"PUBLIC"声明的DTD文件通常是一个由权威机构制订的,提供给特定行业或公众使用的DTD。
DOCTYPE 根元素 PUBLIC "外部DTD的标示名" "外部DTD文件路径"
>
2.元素类型声明
ELEMENT 元素名 元素内容描述
>
DTD中使用的元素内容类型有:EMPTY、ANY、Mixed、Elements
EMPTY是指元素不能有任何的内容,但可以有属性:
ELEMENT 元素1 EMPTY
>
ATTLIST 元素1 性别 (男|女) "男"
>
<
元素1
性别
="女"
/>
ANY说明元素可以有任何类型的子元素,也可以是纯文本,还可以为空
ELEMENT 元素2 ANY
>
这里需要特别注意的是,虽然用ANY定义的元素可以包含其它元素,但必须遵循XML文件的"有效的"原则,即XML文件规定文件中所使用的任何元素都必须在DTD中给出定义
看下面这段非法的文件:
xml version="1.0" encoding="gb2312"
?>
DOCTYPE 图书信息 [
>
]>
<
图书信息
>
<
书名
>
新概念英语
书名
>
图书信息
>
编译器会提示这样一条错误信息
"This file is not valid: Element '书名' has not been declared."
就是提示"书名"这个元素没有经过定义,要纠正这个错误,只要在DTD定义部分加入定义语句""就可以了
Mixed允许混合内容使得字符数据和其他元素能在元素内共存,它并不是以关键字的形式存在的
ELEMENT 元素3 (#PCDATA|子元素1|子元素2)
>
xml version="1.0" encoding="gb2312"
?>
DOCTYPE 图书信息 [
>
ELEMENT 书名 (#PCDATA)
>
ELEMENT 价格 (#PCDATA)
>
]>
<
图书信息
>
今日新到图书:
<
书名
>
XML实用教程
书名
>
<
价格
>
¥26.00
价格
>
图书信息
>
Elements规定特定子元素必须按规则与顺序出现,子元素后可以用各种元字符来说明出现的次数
可能出现的元字符:
元字符 |
含义 |
+ |
出现1次或多次 |
* |
出现0次或多次 |
? |
出现0次或1次 |
无符号 |
只能出现1次 |
下面的例子中,"IT求职"的各项子元素必须按顺序和元字符说明的次数来出现
xml version="1.0" encoding="gb2312"
?>
DOCTYPE IT求职 [
>
ELEMENT 招聘信息 (公司名,招聘职位+,公司网站?,联系方式*)
>
ELEMENT 公司名 (#PCDATA)
>
ELEMENT 招聘职位 (#PCDATA)
>
ELEMENT 公司网站 (#PCDATA)
>
ELEMENT 联系方式 (#PCDATA)
>
]>
<
IT
求职
>
<
招聘信息
>
<
公司名
>
中兴通讯
公司名
>
<
招聘职位
>
1.Java高级工程师
招聘职位
>
<
招聘职位
>
2.C++高级工程师
招聘职位
>
<
公司网站
>
http://www.zte.com.cn/
公司网站
>
<
联系方式
>
地址:深圳市南山区高新技术产业园科技南路中兴通讯大厦
联系方式
>
<
联系方式
>
电话:0755-26770000
联系方式
>
招聘信息
>
<
招聘信息
>
<
公司名
>
阿里巴巴
公司名
>
<
招聘职位
>
软件测试工程师
招聘职位
>
招聘信息
>
IT求职
>
3.定义有效的元素属性
在DTD中定义属性时,我们采用下面的格式:
例如:
姓名 CDATA #REQUIRED
性别 (男|女) "男"
联系方式 CDATA #IMPLIED
>
根据XML文件是否必须为一个属性提供取值,属性的缺省值又可以分为以下四类:
- 必须赋值的属性REQUIRED
- 属性值可有可无的属性IMPLIED
- 固定取值的属性FIXED
- 自定义的缺省值
下面用一个例子来说明这四类缺省属性
xml version="1.0" encoding="gb2312"
?>
DOCTYPE 图书信息 [
>
ELEMENT 书名 (#PCDATA)
>
ELEMENT 作者 (#PCDATA)
>
ELEMENT 价格 (#PCDATA)
>
ATTLIST 作者
姓名 CDATA #REQUIRED
性别 (男|女) "男"
联系方式 CDATA #IMPLIED
分类 CDATA #FIXED "WEB编程技术"
>
]>
<
图书信息
>
<
书名
>
ASP.NET案例开发集锦
书名
>
<
作者 姓名="赵辉、杨丽敏"
/>
<
价格
>
37.00
价格
>
<
书名
>
C#高级编程
书名
>
<
作者 姓名="wrox
" 联系方式
="http://www.wrox.com"
/>
<
价格
>
128.00
价格
>
<
书名
>
HTML XHTML CSS基础教程(第6版)
书名
>
<
作者 姓名="Elizabeth
Castro" 分类
="WEB编程技术"
/>
<
价格
>
50.00
价格
>
<
书名
>
ASP.NET 2.0 应用开发技术
书名
>
<
作者 姓名="孟宪会(net_lover
)" 性别
="男"
/>
<
价格
>
59.00
价格
>
图书信息
>
上面的例子为子元素"作者"定义了4个属性,分别是"姓名"(#REQUIRED类型)、"联系方式"(#IMPLIED类型)、"分类"(#FIXED类型)、"性别"(自定义类型)
在第一本书《ASP.NET案例开发集锦》中,只出现了"姓名",但其实际属性有两项,还有一个是#FIXED类型的"分类"
在第二本书《C#高级编程》中,除了必须出现的"姓名",还出现了#IMPLIED类型的"联系方式",算上#FIXED类型的"分类",实际属性有三项
在第三本书《HTML XHTML CSS基础教程(第6版》中,除了"姓名",还显式出现了#FIXED类型的"分类",它的实际属性与第一本书相同
在第四本书《ASP.NET 2.0 应用开发技术》中,"姓名"后出现了自定义属性"性别",它只有两个值"男"和"女",默认为"男",出现其他值将显示错误
属性类型分为以下10种:
- CDATA
- Enumerated
- ID
- IDREF
- IDREFS
- ENTITY
- ENTITIES
- NMTOKEN
- NMTOKENS
- NOTATION
CDATA和Enumerated(枚举类型)在上面的例子中已有所说明,主要研究一下其他的属性类型:
·ID属性类型
每个ID类型的属性必须有不同的值,大多数ID属性使用#REQUIRED,且ID类型和#FIXED不兼容.属性不能既是固定的,又有ID类型.这是因为#FIXED属性只能有一个值
看下面的错误示例:
xml version="1.0" encoding="UTF-8"
?>
DOCTYPE 职员信息 [
>
ELEMENT 普通职员 (#PCDATA)
>
ATTLIST 普通职员 编号 ID #REQUIRED
>
]>
<
职员信息
>
<
普通职员 编号="8
"
>
张三
普通职员
>
<
普通职员 编号="E8
"
>
李四
普通职员
>
<
普通职员 编号="E8
"
>
王五
普通职员
>
职员信息
>
上面的文件有2个错误,一个是 编号="8" 这里,ID属性不能是纯数字,必须要以字母或下划线开头;另一个是出现了两个"E8"的编号,这与ID属性的定义是相违背的.
·IDREF属性类型
具有IDREF类型的属性的值是文档中另一个元素的ID
xml version="1.0" encoding="gb2312"
?>
DOCTYPE 武将信息 [
>
ELEMENT 姓名 (#PCDATA)
>
ATTLIST 姓名 编号 ID #REQUIRED
>
ATTLIST 姓名 君主 IDREF #IMPLIED
>
]>
<
武将信息
>
<
姓名 编号="P1
"
>
曹操
姓名
>
<
姓名 编号="P2
"
>
刘备
姓名
>
<
姓名 编号="P3
"
>
孙权
姓名
>
<
姓名 编号="P4
" 君主
="P1">
许楮
姓名
>
<
姓名 编号="P5
" 君主
="P2">
关羽
姓名
>
<
姓名 编号="P6
" 君主
="P3">
甘宁
姓名
>
武将信息
>
上面的例子中,由于"君主"属性指定为IDREF,所以其内容必须为ID属性的"编号"里的值
·IDREFS属性类型
IDREF属性的值只能为一个.但如果要描述一对多的关系,例如三国里所有人都只有一个君主,但却会有多个子女.这时候就要用到IDREFS属性了
xml version="1.0" encoding="gb2312"
?>
DOCTYPE 武将信息 [
>
ELEMENT 姓名 (#PCDATA)
>
ATTLIST 姓名 编号 ID #REQUIRED
>
ATTLIST 姓名 子女 IDREFS #IMPLIED
>
]>
<
武将信息
>
<
姓名 编号="C1
"
>
关平
姓名
>
<
姓名 编号="C2
"
>
关兴
姓名
>
<
姓名 编号="C3
"
>
孙策
姓名
>
<
姓名 编号="C4
"
>
孙权
姓名
>
<
姓名 编号="C5
"
>
孙尚香
姓名
>
<
姓名 编号="F1
" 子女
="C1 C2">
关羽
姓名
>
<
姓名 编号="F2
" 子女
="C3 C4 C5">
孙坚
姓名
>
武将信息
>
·ENTITY属性类型
ENTITY类型属性使人们能把外部二进制数据(即外部未解析的普通实体)链接到文档,ENTITY属性的典型例子是一幅图像,该图像由来自与另一个URL的二进制数据组成
xml version="1.0" encoding="UTF-8"
?>
DOCTYPE 图像 [
>
ATTLIST 图像 来源 ENTITY #REQUIRED
>
ENTITY Logo SYSTEM "logo.gif"
>
]>
<
图像 来源="&Logo
;"
/>
·ENTITIES属性类型
ENTITIES是ENTITY的复数形式.ENTITIES类型的属性值由空格分隔多个未解析的实体名称组成.每个实体名称引用一个外部的非XML数据源.这个方法的一个用途是轮流显示不同图片的幻灯片,如下所示:
xml version="1.0" encoding="gb2312"
?>
DOCTYPE 幻灯片 [
>
ATTLIST 幻灯片 来源 ENTITY #REQUIRED
>
ENTITY PIC1 SYSTEM "picture1.jpg"
>
ENTITY PIC2 SYSTEM "picture2.gif"
>
ENTITY PIC3 SYSTEM "picture3.jpg"
>
]>
<
幻灯片 来源="&PIC1
; &PIC2; &PIC3;"
/>
·NMTOKEN属性类型
NMTOKEN属性类型限制有效的XML名称记号的属性值,除了空格,任何字符都被认为是有效的.
xml version="1.0" encoding="gb2312"
?>
DOCTYPE 客户资料 [
>
ELEMENT 联系地址 (#PCDATA)
>
ATTLIST 联系地址 城市 NMTOKEN #REQUIRED
>
]>
<
客户资料
>
<
联系地址 城市="London
"
>
张三
联系地址
>
<
联系地址 城市="010
北京"
>
李四
联系地址
>
<
联系地址 城市="New
York"
>
王五
联系地址
>
客户资料
>
上面的例子,"010北京"虽然是以数字开头,但由于是NMTOKEN类型,所以它也是合法的.但最后的"New York"为非法,因为NMTOKEN类型限制了空格的使用
·NMTOKENS属性类型
NMTOKENS是NMTOKEN的复数形式,它允许出现一组值,同NMTOKEN的规则一样,不限制符号的使用。它可以出现空格,但空格的作用是分割不同的记号
xml version="1.0" encoding="gb2312"
?>
DOCTYPE 注册信息 [
>
ELEMENT 用户资料 (#PCDATA)
>
ATTLIST 用户资料 爱好 NMTOKENS #REQUIRED
>
]>
<
注册信息
>
<
用户资料 爱好="足球 篮球"
>
张三
用户资料
>
<
用户资料 爱好="唱歌 跳舞"
>
李四
用户资料
>
<
用户资料 爱好="Play
the Piano"
>
王五
用户资料
>
注册信息
>
上面的例子虽然没有错误,但最后的"play the piano"本来想表达的意思是"弹钢琴",但由于NMTOKENS的限制,被拆解成了"play"、"the"、"Piano"三个部分。所以在遇到NMTOKENS类型属性时,要特别注意空格的使用。
·NMTOKENS属性类型
NOTATION对于使用非XML格式的数据非常有用。现实世界中存在很多无法或不易用XML格式组织的数据,例如图象、声音、影象等等。对于这些数据,XML应用程序常常并不提供直接的应用支持。通过为它们设定NOTATION类型的属性,可以向应用程序指定一个外部的处理程序
xml version="1.0" encoding="gb2312"
?>
DOCTYPE 文件 [
>
ELEMENT 声音文件 (#PCDATA)
>
NOTATION MP SYSTEM "mplayer32.exe"
>
NOTATION ST SYSTEM "soundtool"
>
NOTATION SM SYSTEM "Sound Machine"
>
ATTLIST 声音文件 处理程序 NOTATION (MP|SM|ST) #REQUIRED
>
]>
<
文件
>
<
声音文件 处理程序="MP
"
>
Lydia.mp3
声音文件
>
文件
>