DTD
Document Type Definition.
一.在XML文档中引入DTD
内部DTD
声明格式: <!DOCTYPE 根元素名称[...这里是DTD具体的内容...]>
内部DTD的优点
直观,修改方便,不需要担心XML处理器找不到DTD.
内部DTD的缺点
使XML文件变长.无法共享DTD.
外部DTD
DTD文档的文件名
只能包含ASCII字母和数字字符,空格,回车符,换行符和一些标点符号 -'()+,./:=?;!*#@$_% 注意:Windows文件的命名规则没有这么严厉.
声明私有DTD文件的格式:<!DOCTYPE 根元素名称 SYSTEM "外部DTD文件的URI.dtd">
SYSTEM:表示使用私有DTD.
外部DTD文件的URI:可以是绝对,也可以是相对.这部分也称为 系统标识符 .
声明公共DTD文件的格式:<!DOCTYPE 根元素名称 PUBLIC "DTD文件" "外部DTD文件的URI.dtd">
PUBLIC:表示使用公共的DTD.
"外部DTD文件的URI.dtd":称为 公共标识符.
"DTD文件":
如果是IOS的标准组织批准的DTD,它的名称以 + 开始.
如果不是IOS的DTD,它的名称以 - 开始.
开始字符串后跟双斜杠 // ,再接DTD所有者的名字,再接双斜杠 // ,再接ISO639语言标识符(英语为EN,中文为ZH).
如:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
说明:W3C不是官方所批的标准组织.但由于它的权威性使它成为事实上的标准.
二.DTD的结构
DTD由元素类型,属性表声明,实体声明,记号声明等构成.
DTD通过元素之间的父子关系,描述整个文档的结构关系.
DTD的文档结构如下:
第一行是DTD声明部分 该声明与xml文档的生命语法格式相同
0到多个注释部分,DTD注释与xml文档的注释完全相同
0到多个<!ELEMENT…>定义 每个它就是一个xml元素
0到多个<!ATTLIST…>定义 每个它就是一个xml元素的属性
0到多个<!ENTITY…>定义 每个它就是一个实体
0到多个<!NOTATION…>定义 每个它定义一个符号
彼此之间完全独立,无须相互嵌套。
1.元素类型声明
说明DTD中可以存在的元素,给出元素的名称,给出元素的具体类型.
语法格式:<!ELEMENT 元素名称 (元素内容形式)>
元素内容形式:
(1)#PCDATA
关键字,说明元素包含字符数据.
(2)元素型内容
说明元素包含子元素.当一个元素只包含一个子元素,没有字符数据时,则称此元素类型具有元素型内容.
内容模型是决定子元素类型和子元素出现顺序的一种简单语法.
例:XML文档中
<?xml version="1.0" encoding="GB2312"?> <!DOCTYPE hr[ <!ELEMENT hr(employee)> <!ELEMENT employee(#PCDATA)> ]> <hr> <employee>雇员</employee> </hr>
如果xml元素内有多个子元素.可以在圆括号 ( ) 中包含子元素名称,子元素之间用逗号 , 分隔.
用逗号隔开的一系列子元素成为一个序列,表示这些元素在文档中要严格按照序列的顺序出现在文档中.
例:
<?xml version="1.0" encoding="GB2312"?> <!DOCTYPE hr[ <!ELEMENT hr(employee)> <!ELEMENT employee(name,age,sex)> <!ELEMENT name(#PCDATA)> <!ELEMENT age(#PCDATA)> <!ELEMENT sex(#PCDATA)> ]> <hr> <employee><?xml version="1.0" encoding="GB2312"?> <name>剑圣</name> <age>128</age> <sex>男</sex> </employee> </hr>
如果xml元素的子元素是多个元素中的一个,有且只有一个.可以在圆括号 ( ) 中包含子元素名称,子元素之间用竖线 | 分隔.
<!DOCTYPE hr[ <!ELEMENT hr(employee)> <!ELEMENT employee(name,age,sex)> <!ELEMENT name(#PCDATA)> <!ELEMENT age(#PCDATA)> <!ELEMENT sex(#PCDATA)> <!ELEMENT salary(cash|credit_cash)> ...... ]>
如果xml元素中的某个子属性可以存在任意多个,即可以没有,也可以有多个.可以在该属性后添加星号 * .
<?xml version="1.0" encoding="GB2312"?> <!DOCTYPE hr[ <!ELEMENT hr(employee)> <!ELEMENT employee((name,age,sex),interest*)> <!ELEMENT name(#PCDATA)> <!ELEMENT age(#PCDATA)> <!ELEMENT sex(#PCDATA)> <!ELEMENT interest(#PCDATA)> ]> <hr> <employee><?xml version="1.0" encoding="GB2312"?> <name>剑圣</name> <age>128</age> <sex>男</sex> <interest>杀农民</interest> <interest>砍山丘</interest> </employee> </hr>
如果xml元素中的某个子属性至少需要一个.可以在该属性后添加加号 + .
<?xml version="1.0" encoding="GB2312"?> <!DOCTYPE hr[ <!ELEMENT hr(employee)> <!ELEMENT employee((name,age,sex),interest+)> <!ELEMENT name(#PCDATA)> <!ELEMENT age(#PCDATA)> <!ELEMENT sex(#PCDATA)> <!ELEMENT interest(#PCDATA)> ]> .......
如果xml元素中的某个子属性最多只有一个,即0个或1个.可以在该属性后添加问号 ? .
<?xml version="1.0" encoding="GB2312"?> <!DOCTYPE hr[ <!ELEMENT hr(employee)> <!ELEMENT employee((name,age,sex),interest+,spouse?)> <!ELEMENT name(#PCDATA)> <!ELEMENT age(#PCDATA)> <!ELEMENT sex(#PCDATA)> <!ELEMENT interest(#PCDATA)> ]> .......
复合形式
例:
<!ELEMENT 简历(名字,性别,年龄,(电话|手机),家庭住址?,兴趣爱好*,教育经历+,工作经验*)>
(3)混合内容
表明元素既可以包含字符数据,也可以包含子元素.混合内容必须被定义零个或多个。
要注意的是:在使用混合内容模型时,#PCDATA关键字必须是模型中的第一个选项,不能再模型中使用逗号,问号,或加号.只用竖线分割是合法的,其他分割都是非法的.
例:
<?xml version="1.0" encoding="GB2312"?> <!DOCTYPE employee[ <!ELEMENT employee(#PCDATA|name)*)> <!ELEMENT name(#PCDATA)> ]> <hr> <employee> 宇宙第三 <name>剑圣</name> </employee> </hr>
(4)EMPTY
关键字,说明元素是一个空元素.
例:在html中声明br标签, <!ELEMENT br EMPTY> .
(5)ANY
关键字,说明该元素可以包含任何字符数据和子元素.只要不违反XML格式良好的约束即可.在实际使用中,应该尽量避免使用ANY。
例:<!ELEMENT employee ANY> .
2.实体声明
DTD中的特殊符号使用引用实体声明: &符号编码;
在多个文档中调用相同的内容,为了避免重复输入这些内容.则可以声明一个实体来表示这些内容,在文档中只需要引用这个实体,经过XML处理器对文档进行分析处理后,引用实体的位置会被实体的内容所替换.
实体用ENTITY关键字声明
(1)一般实体和参数实体
一般实体
一般实体声明格式:<!ENTITY 实体名 “实体内容”>
实体的使用格式: &实体名; (与特殊符号的引用实体一致)
<?xml version=”1.0” encoding=”GB2312”?> <!DOCTYPE website[ <!ELEMENT website(name,copyright)> <!ELEMENT name (#PCDATA)> <!ELEMENT copyright(#PCDATA)> <!ENTITY name “程序员之家”> <!ENTITY copyright “©2004,程序员之家,All Rights Reserved”> ]> <webstie> <name>&name;</name> <copyright>©right;</copyright> <website>
参数实体
参数实体只能在DTD内使用使用.
声明格式:<!ENTITY % 实体名 “实体内容”>
注意ENTITY,%, 实体名,之间各有一个空格.
引用参数实体的方式: %实体名;
例:
以下是一个dtd文件 website.dtd. <?xml version=”1.0” encoding=”GB2312”?> <!DOCTYPE website[ <!ELEMENT website(name,copyright)> <!ELEMENT name (#PCDATA)> <!ELEMENT copyright(#PCDATA)> <!ENTITY % name “程序员之家”> <!ENTITY copyright “©2004,%name; ,All Rights Reserved”> ]> 以下是xml文件 web.xml <?xml version=”1.0” encoding=”GB2312”?> <!DOCTYPE website SYSTEM “website.xml”> <webstie> <name>程序员之家</name> <copyright>©right;</copyright> <website>
当参数实体引用出现在标记声明内部的时候,DTD应该放在外部子集中.在内部DTD子集中,参数实体引用不能再标记声明的内部出现,但可以在标记声明允许出现的地方出现.
在内部DTD中,参数实体引用只能标记在声明之外使用.
例:
<?xml version=”1.0” encoding=”GB2312”?> <!DOCTYPE website[ <!ELEMENT website(name,copyright)> <!ELEMENT name (#PCDATA)> <!ELEMENT % cprt “<!ELEMENT copyright (#PCDATA)>”> %cprt; <!ENTITY copyright “©1991,落日酒馆; ,All Rights Reserved”> ]> <webstie> <name>程序员之家</name> <copyright>©right;</copyright> <website>
在DTD中,所有参数实体必须在引用之前进行声明.这意味着内部DTD子集不能引用在外部DTD中声明的参数实体,这是因为XML处理器将首先读取内部子集,也就是说,内部子集中的实体和属性表声明的优先级要比在外部子集中得高.
(2)内部实体和外部实体
内部实体在XML文档内部定义,实体的内容在声明中给出.内部实体都是已解析的实体,它们没有单独的物理存储对象.
外部实体在单独的(外部)文件中定义,外部实体可以是已解析实体,也可以是未解析实体.
外部一般实体的声明形式如下:<!ENTITY copyright SYSTEM “http://www.........”>
SYSTEM表明这是一个私有的外部一般实体,后面的URI称为该实体的系统标识符.
3.属性声明
属性表声明
属性用于将名字-值对与元素进行关联.属性说明只能在开始标签和空元素标签中出现.
属性表声明详细说明了与给定元素类型相关联的每一个属性的名字,数据类型和默认值.
格式:<!ATTLIST 元素名 属性名 属性类型 默认声明>
CDATA 字符串数据 character data
(e1|e2|e3) 该属性是一系列枚举值之一
ID 当前属性表示唯一的id.
IDREF 引用已经定义的id
IDREFS 空格区分多个id
ENTITY 一个外部的实体
ENTITIES 多个外部实体,多个外部实体之间用空格分隔
NMTOKEN
NMTOKENS
NOTATION
(2)默认声明
#REQUIRED 说明该属性必须存在.
#IMPLIED 说明该属性可有可无.
#FIXED 默认值 说明一个固定的属性默认值,文档的编写者不能修改该属性的值.
只有默认值 若元素中没有当前属性,则该属性的值为设置的默认值.
很多数据无法用XML来表示,如声音,图像,影像等.通过DTD记号声明为非XML数据描述一种可能的格式,或者指定一个外部处理程序.
记号声明有两种形式,一种是使用MIME类型.
<!NOTATION gif SYSTEM “image/gif”>
另一种是使用URI路径,指出外部处理程序的位置.
<!NOTATION gif SYSTEM “iexplore.exe”>
记号的声明也可以使用PUBLIC代替SYSTEM,并添加公共的名称和URI.