DTD的基本概念
DTD概述
DTD基本概念
DTD是 Document Type Definition 文档类型定义的缩写。
XML是用来描述标记语言的语言,可以由DTD定义结构,包括标记,属性和实体以及这些内容的相互关系
DTD基本结构
分为外部DTD和内部DTD
- 内部DTD
<?xml version="1.0" standalone="yes" ?>
<!DOCTYPE DOCUMENT [
<!ELEMENT DOCUMENT (TITLE)>
<!ELEMENT TITLE (#PCDATA)>
] !>
<DOCUMENT>
<TITLE>空元素</TITLE>
</DOCUMENT>
以上是内部DTD,在XML文件的顶部声明。
- 外部DTD
<!DOCTYPE 根元素 SYSTEM URL
<?xml version="1.0" standalone="no" ?>
<!DOCTYPE DOCUMENT SYSTEM "url">
<DOCUMENT>
<TITLE>空元素</TITLE>
</DOCUMENT>
- 混合使用
<?xml version="1.0" standalone="no" ?>
<!DOCTYPE DOCUMENT SYSTEM "url"
[
<!-- 内部DTD -->
]>
<Document>
<TITLE>空元素</TITLE>
</Document>
元素声明
语法 <!ELEMENT 元素名 内容说明 >
元素内容类型
内容说明有以下五种
-
空元素 => EMPTY
-
任意 => ANY
-
字符数据 => #PCDATA
-
描述子元素顺序和重复次数的内容模型 => Children
-
混合 => Mixed
EMPTY
<!ELEMENT img EMPTY>
<img ... />
ANY
顾名思义,什么都行。
#PCDATA
<!ELEMENT book (#PCDATA)>
<book>hello world</book>
内部只能包含字符数据,不能包含子元素
Mixed
可以声明任何元素字符数据等任意组合
<! ELEMENT anyelement (字符数据|子元素|实体)*>
<! ELEMENT music (#PCDATA|name|singer)* >
<music>
<name>消愁</name>
<singer>毛不易</singer>
好听的歌曲
</music>
Children类型
可以声明包含哪些子元素,并指定次序和出现次数
<! ELEMENT anyelement (子元素内容模型)>
- 次序 用逗号表示
<!ELEMENT SIGNATURE (HR,COPYRIGHT,BR,EMAIL,BR,LAST_MODIFIED)>
<SIGNATURE>
<HR/>
<COPYRIGHT>2001年</COPYRIGHT>
<BR/>
<EMAIL>webmaster@eastdajia.com </EMAIL>
<BR/>
<LAST_MODIFIED>2001年12月</LAST_MODIFIED>
</SIGNATURE>
- 选择 用竖线表示
<!ELEMENT PAYMENT (CASH|CREDIT_CARD)>
<PAYMENT>
<CASH>100</CASH>
</PAYMENT>
- 选择和次序的组合
<!ELEMENT message (header,body,(signature|footer))>
元素出现次数指示符
- ? => 表示出现0次或1次
- * => 表示出现任意次
- + => 表示出现至少一次
<!ELEMENT SCHOOL (SCHOOL_CITY,SCHOOL_NAME,STUDENT*)>
一个综合例子
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE 班级 [
<!ELEMENT 班级 (学生+)>
<!ELEMENT 学生 (ID, 姓名,性别, 出生日期*, 年龄?, 住址, 电话, 爱好)>
<!ELEMENT ID (#PCDATA)>
<!ELEMENT 姓名 (#PCDATA)>
<!ELEMENT 性别 (#PCDATA)>
<!ELEMENT 出生日期 (#PCDATA)>
<!ELEMENT 年龄 (#PCDATA)>
<!ELEMENT 住址 (#PCDATA)>
<!ELEMENT 电话 EMPTY>
<!ELEMENT 爱好 ((#PCDATA|运动|阅读|游戏)*) >
<!ELEMENT 运动 (#PCDATA)>
<!ELEMENT 阅读 (#PCDATA)>
<!ELEMENT 游戏 (#PCDATA)>
]>
<班级>
<学生>
<ID>0001</ID>
<姓名>张平</姓名>
<性别>男</性别>
<出生日期>1984.6.5</出生日期>
<年龄>23</年龄>
<住址>新鸿大街26号</住址>
<电话/>
<爱好>
杂志
<运动>游泳</运动>
<运动>排球</运动>
<阅读>红与黑</阅读>
</爱好>
</学生>
<学生>
<ID>0002</ID>
<姓名>李晓虹</姓名>
<性别>女</性别>
<出生日期>1983.1.15</出生日期>
<出生日期>1983.2.27</出生日期>
<住址>康乐小区2265号</住址>
<电话/>
<爱好>
小说
<运动>跳舞</运动>
</爱好>
</学生>
</班级>
属性声明
<! ATTLIST 元素名 属性名 属性类型 默认声明 默认值>
<!ATTLIST year format CDATA #IMPLIED>
<year format="numeric">
2010
</year>
默认声明
- REQUIRED 必须有这个属性
- IMPLIED 不是必须有的属性
- FIXED 不必明确指明,用默认值,如果要明确指定属性值,必须是属性定义给出的默认值
<!ATTLIST book isbn CDATA #FIXED '2312'>
<book></book>
<!-- <book isbn="2312"></book> -->
属性类型
- CDATA
意味着属性必须是字符集合
- Enumerated
从一组给定的值中选择一个作为属性值
<!ATTLIST play position (center|forward|defenseman) "center" >
- ID类型
<!ATTLIST film class ID #REQUIRED>
表示每一个属性值在XML文档中必须是唯一的,ID属性的取值不可以用数字开头
- IDREF类型
必须引用XML文档或者其他元素ID类型属性的值
<?xml version ="1.0"standalone="yes"?>
<!DOCTYPE DOCUMENT [
<!ELEMENT DOCUMENT (PERSON*)>
<!ELEMENT PERSON (#PCDATA)>
<!ATTLIST PERSON PNUMBER ID #REQUIRED>
<!ATTLIST PERSON FATHER IDREF #IMPLIED>
<!ATTLIST PERSON MOTHER IDREF #IMPLIED>
]>
<DOCUMENT>
<PERSON PNUMBER="a1">Susan</PERSON>
<PERSON PNUMBER="a2">Jack</PERSON>
<PERSON PNUMBER="a3“ MOTHER="a1“ FATHER="a2">Chelsea</PERSON>
<PERSON PNUMBER="a4“ MOTHER="a1“ FATHER="a2">David</PERSON>
</DOCUMENT>
- IDREFS 类型
<!ATTLIST author authorID ID #REQUIRED>
<!ATTLIST author IDREFS #REQUIRED>
<author authorID="a001" />
<author authorID="a002" />
<book author="a001 a002"></book>
- ENTITY 类型
将外部二进制数据文件或者不可解析实体连接到XML中
<!ENTITY qhPress SYSTEM "xxx">
<!ATTLIST press publisher ENTITY #REQUIRED>
<press publisher="&qhPress;" />
- ENTITYS 类型
将多个连接到XML文档中
<!ENTITY qhPress SYSTEM "xxx">
<!ENTITY fzuPress SYSTEM "xxx">
<!ATTLIST press publisher ENTITYS #REQUIRED>
<press publisher="&qhPress;&fzuPress" />
- NMTOKEN 类型
属性值是一个有效的XML名称记号
<!ELEMENT paragraph (#PCDATA)>
<!ALLIST paragraph size NMTOKEN #REQUIRED>
<paragraph size=“one_line”></paragraph>
<paragraph size=“two_lines ”></paragraph>
- NMTOKENS 类型
<!ELEMENT paragraph (#PCDATA)>
<!ALLIST paragraph size NMTOKENS #REQUIRED>
<paragraph size=“one_line two_line”></paragraph>
-
NOTATION 类型
没看懂
<!NOTATION gif SYSTEM “image/gif”>
<!NOTATION jpg SYSTEM “image/jpg”>
<!NOTATION png SYSTEM “image/png”>
<!ELEMENT img EMPTY>
<!ATTLIST img src ENTITY #REQUIRED>
<!ENTITY SOURCE SYSTEM “a.gif” NDATA gif>
<img src=“SOURCE” />
条件语句
有时候有些没用的DTD除了用注释还可以用IGNORE指令封装
<!ENTITY % ignore "IGNORE">
<!ENTITY % include "INCLUDE">
<![%ignore;[
<!ELEMENT 图书馆A (科技类,文艺类,社科类)>
]]>
<![%include;[
<!ELEMENT 图书馆B (科技类,社科类,少儿类)>
]]>
<!ELEMENT 科技类 (#PCDATA) >
<!ELEMENT 文艺类 (#PCDATA) >
<!ELEMENT 社科类 (#PCDATA) >
<!ELEMENT 少儿类 (#PCDATA) >
练习
下表是磁盘信息表,请根据该表格,写出表示该表格的XML文档,
并定义该文档的DTD。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mfB0IMct-1609259070307)(C:\Users\MSI\AppData\Roaming\Typora\typora-user-images\image-20201227140134374.png)]
<!DOCTYPE 磁盘[
<!ELEMENT 磁盘 (品名, 规格, 型号,容量, 尺寸, 价格, 库存) >
<!ELEMENT 品名 (#PCDATA)>
<!ELEMENT 规格 (#PCDATA)>
<!ELEMENT 型号 (#PCDATA)>
<!ELEMENT 容量 (#PCDATA)>
<!ELEMENT 尺寸 (#PCDATA)>
<!ELEMENT 价格 (#PCDATA)>
<!ELEMENT 库存 (#PCDATA)>
<!ATTLIST 价格 货币 CDATA #REQUIRED '元'>
<!ATTLIST 库存 单位 CDATA #REQUIRED '盒'>
]>