DTD是一套关于标记的语法规则,它定义了文档的逻辑结构,规定了文档中所使用的元素、实体、元素的属性、元素与实体之间的关系。
一、 引入DTD (3种方式)
内部DTD——内部的DTD紧跟在XML声明和处理指令之间。
< ? xml version=”1.0” encoding=”GB2312” standalone=”yes” ?>
<! DOCTYPE 根元素名称 [
<! ELEMENT 子元素名称 (#PCDATA)>
]>
2、外部DTD
外部文件类型定义存在于独立文件中,文件扩展名为“dtd”。外部DTD的了处:可以方便地被多个XML文档共享,只需要定义一份DTD文档,即可为多个XML文档定义语义约束。
<!DOCTYPE 根元素名 SYSTEM " DTD-URL ">
SYSTEM:关键字,指该外部DTD是私有的
DTD-URL:通过URL将外部DTD引用到XML文档中,可以是绝对地址也是可以相对地址。
3、公用DTD
<!DOCTYPE 根元素名 PUBLIC " DTD-NAME “ “DTD-URL”>
公用DTD与外部DTD区别在于:公用DTD使用PUBLIC代替了原来的SYSTEM,并增加了DTD标识名。
二、 DTD文档的结构
<?xml version="1.0" encoding="UTF-8"?> DTD声明部分,DTD注释与XML注释的语法完全相同
<!ELEMENT …>定义一个XML元素
<!ELEMENT …>
…
<!ATTLIST …>定义一个XML元素定义了一个属性
<!ATTLIST …>
…
<!EMTITY…>定义一个实体
…
<!NOTATION…>定义一个符号
...
三、DTD对元素声明【重点】
使用ELEMENT声明XML元素的语法, <!ELEMENT 元素名 元素内容>
注:元素声明以“<!”开始,以“>”结束;
元素声明指令“ELEMENT”为关键字,必须大写;
元素名:为当前元素指定的元素名称;
元素内容:元素名后面的内容用来指定元素的内容类型,可分为EMPTY(空)、子元素类型,混合型、ANY(任意)和#PCDATA 五种类型;
DTD必须定义XML文档中允许出现的所有元素。由此可见,虽然XML文档允许开发者自由扩展各种标签,但一旦使用DTD为其增加了语义约束,该XML文档就只能出现在DTD中定义过的元素。
1、 空元素类型——EMPTY 语法:<!ELEMENT 元素名 EMPTY>
2、 任意类型的元素——ANY 语法:<!ELEMENT 元素名 ANY>
3、 字符串内容的元素——#PCDATA 语法:<!ELEMENT 元素名 #PCDATA>
4、 混合内容元素 语法:<!ELEMENT 父元素名 (#PCDATA|子元素1|子元素2|子元素3…..)*>
注意:
#PCDATA必须放在最前面
#PCDATA和各子元素之间只能用竖线(|)分割
子元素1,子元素2和子元素3之间的竖线(|)并不是表示互斥,而只是表 示这些元素能无序的重复出现,而且次数不受限制
不要试图在各个子元素之后添加?,*。+等表示频率的修饰符
四、 定义子元素
有序的子元素 互斥的子元素 无序的子元素
1.有序的子元素——用英文逗号,作为子元素之间的分隔符,则子元素之间必须遵守所定义的顺序。
2.互斥的子元素——互斥的子元素表明一系列子元素之间只能出现
其中一次。互斥子元素使用竖线(|)分隔,以竖线(|)分隔的多个元素只能出现其中之一。
3.无序的子元素
从理论上讲,DTD没有专门为定义无序子元素提供语法,如果希望使用DTD来表示某个元素之内可以接受无序的子元素。
注:+: 表明子元素可以出现1次或多次*: 表明子元素可以出现0次或多次 ?: 表明子元素可以出现0次或1次
**组合子元素——<!ELEMENT 计算机书籍 ((书名,作者)+,价格,简要介绍)>
五、 DTD对属性声明【重点】
在 DTD 中,属性通过 ATTLIST 声明来进行声明。一个属性声明可以声明一个元素的多个属性。
<! ATTLIST 元素名 属性名 属性类型 [属性限定条件] [默认值]>
注:“属性限定条件”和“默认值‘两部分是可选的吗,有下面几种情况
在没有指定“元素对属性的约束”时,必须为该属性指定“默认值”;
当“元素对属性的约束”是#REQUIRED时,不能为该属性指定“默认值”;
当“元素对属性的约束”是“IMPLIED”时,不能为该属性指定“默认值”;
当“元素对属性的约束”是“FIXED”时,必须为该属性指定“默认值”;
六、 定义属性类型【重点】
DTD支持的属性类型
属性类型 | 含义 |
CDATA | 值为字符串数据 |
(en1|en2|..) | 此值是枚举列表中的一个值 |
ID | 该属性值必须是有效地标识符,在XML文档时唯一的 |
IDREF | 值为另外一个元素的 id属性值 |
IDREFS | 值必须引用自多个已经有的ID属性值,多个ID属性值用空格隔开 |
NMTOKEN | 值为合法的 XML 名称 |
NMTOKENS | 值为多个合法的 XML 名称的列表 |
ENTITY | 值是一个外部实体,如图片支持 |
ENTITIES | 值是一个实体列表,多个实体之间以空格隔开 |
NOTATION | 该属性值是在DTD中声明过的符号,这个是过期的,不要使用 |
七、 字符类型
CDATA 是简单的纯文本字符类型,是最常用的类型,将简单的文本用做属性值。可以包括任何字符串,但不允许使用“<”,“>”,“&”,“””,“‘”。如果需要使用必须使用实体引用。属性值和元素内容都可以是文本类型,但是定义的方法不同
<! ATTLIST Student name CDATA #REQUIRED>
八、 枚举类型、ID、IDREF、IDREFS类型、NMTOKEN和NMTOKENS类型
枚举类型——声明了属性的备选值列表,属性必须从该列表中选择一个值作为属性值。
ID——ID类型是一种较为严格的约束,它要求属性值必须是有效地XML标识名,而且在整个XML文件档中其值不能重复。
IDREF——只能取其他元素设定的ID值
IDREFS——可以一次引用多个属性值,复数引用
NMTOKEN——是一个比ID类型更宽松的类型,只要求该属性是一个合法的XML标识。
NMTOKENS——复数引用,属性值可以取多个合法的XML标识,用空格隔开。
九、 实体定义
1.所谓实体引用就是用一个字符串代替另一个字符串。定义实体有如下作用:
提高代码的服用,方便修改,维护XML文档;
使用某些特殊的符号,这些特殊的符号可能会使XML解析器混淆;
减少字符输入量,如果某个字符串特别长,而且需要经常使用,则可以定义为实体。
2.实体的分类
(1)按照实体的具体内容来分类,实体可分为可解析与不可解析两类。可解析实体的具体内容为简单的字符、数字、文本块,而不可解析实体的具体内容则为图片、声音等二进制文件。
(2)按照逻辑存储来分类,实体可分为内部实体与外部实体两类。内部实体的内容是在文档内部设定的;而外部实体则是一个外部独立的物理存储对象,如某个外部文件。
(3) 按照使用的范围来分类,实体可分为一般实体与参数实体两类。一般实体都用来构成文档的具体内容,可出现在XML文档中,也可出现在DTD中;而参数实体只能出现在DTD中,不能出现在XML文档中。
3.定义普通实体
普通实体是在XML文档里使用的实体,语法:<! ENTITY 实体名 “实体值”>
使用实体的语法:&实体名;
4.定义参数实体
参数实体是在DTD文档里使用的实体,语法:<! ENTITY % 实体名 “实体值”>
使用实体的语法:&实体名;
5.外部普通实体
外部实体的值不在DTD中直接指定,而是专门提供一个文件为该实体指定值----“实体值所在的文件的URL”处的文件来指定。定义外部实体的语法格式:
<! ENTITY 实体名 SYSTEM “实体值所在文件的URI”>
<! ENTITY 实体名 PUBLIC “公用实体标识名” “实体值所在文件的URI”>
6.外部参数实体
类似于定义内部参数实体,语法:<!ENTITY %实体名 SYSTEM|PUBLIC[“公用实体标识名”] “实体值所在文件的URI”>