DTD文档
DTD概述
- DTD是Document Type Definition(文档类型定义)的缩写。
- XML文档是一种描述标记语言的语言,它可以由DTD来定义结构(如文档中的元素、属性等)。
- 定义了可用在xml文档中包含哪些标记(Tag)、属性(Attribute)、实体(Entities)以及这些内容之间的相互关系。
- DTD 使用形式语法来描述符合它的XML文档的结构和语法;它们指定 XML 文档所允许的内容和值。
- DTD分为外部DTD和内部DTD两种。
内部DTD
<! DOCTYPE 根元素名 [
internal.subset
]>
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE DOCUMENT [
<!ELEMENT DOCUMENT (TITLE,SIGNATURE)>
<!ELEMENT TITLE (#PCDATA)>
<!ELEMENT COPYRIGHT (#PCDATA)>
<!ELEMENT EMAIL (#PCDATA)>
<!ELEMENT BR EMPTY>
<!ELEMENT HR EMPTY>
<!ELEMENT LAST_MODIFIED (#PCDATA)>
<!ELEMENT SIGNATURE (HR , COPYRIGHT, BR , EMAIL, BR ,LAST_MODIFIED)>
]>
<DOCUMENT>
<TITLE>空元素</TITLE>
<SIGNATURE>
<HR/>
<COPYRIGHT>2001年</COPYRIGHT><BR/>
<EMAIL>webmaster@eastdajia.com </EMAIL><BR/>
<LAST_MODIFIED>2001年12月</LAST_MODIFIED>
</SIGNATURE>
</DOCUMENT>
外部DTD
如果有多个文档要使用同一个DTD,则该DTD可被置于一个单独的文当中(注意DTD文件的文件扩展名为dtd)。
<?xml version="1.0" standalone="no"?>
<!DOCTYPE customer SYSTEM "http://www.myserver.com/xml/customer.dtd">
<customer>
<name>Michael Calder</name>
<address>
<street>44 McMahons Rd</street>
<suburb>Frankston</suburb>
</address>
</custome>
一个XML文档可以同时使用内部和外部DTD,即给该特定文档的外部DTD添加附加的声明。
<?xml version="1.0" standalone="no"?>
<!DOCTYPE customer SYSTEM "http://www.myserver.com/xml/customer.dtd"
[
<!-- internal DTD declarations go here -->
]>
<customer>
…
</custome>
元素声明
元素声明:声明XML文档中可出现的元素、元素之间的关系、元素的属性等。
语法形式:
<!ELEMENT 元素名 内容说明>
内容说明由以下五种之一组成:
--空元素 EMPTY
EMPTY用于定义空元素,即该元素只可能有属性而不会有字符数据或子元素。
声明空元素的语法是:
<! ELEMENT emptyelement EMPTY>
例:
<!ELEMENT img EMPTY>
则,在XML文档中:
<img …./>
--任意 ANY
这种类型的元素声明是:
<!ELEMENT anyelement ANY>
这表明该元素可以包含DTD中定义的其它任何元素、字符数据、实体参考等。
例:
<!ELEMENT book ANY>
但ANY类型产生了不确定性,应避免使用它。但可以用它来简化调试过程。
--字符数据 #PCDATA
这种类型的元素声明是:
<! ELEMENT anyelement (#PCDATA)>
不包含其他子元素而只包含字符数据的元素,用关键字#PCDATA进行定义。
例:
<!ELEMENT book (#PCDATA)>
--描述子元素的顺序和重复次数的内容模型 Children
这表明该元素可以包含一系列的子元素,并用子元素内容模型指明可以包含哪些子元素,其出现的次序及次数等。
这种类型的元素声明是:
<! ELEMENT anyelement (子元素内容模型)>
例:
<!ELEMENT SIGNATURE (HR , COPYRIGHT, BR , EMAIL,BR ,LAST_MODIFIED)>
根据子元素间的关系,子元素内容模型可以有两种可能的结构:序列和选择。
序列:
所有的子元素必须出现且仅出现一次,而且要依次出现。
例:
<!ELEMENT SIGNATURE (HR , COPYRIGHT, BR , EMAIL,BR ,LAST_MODIFIED)>
对应的XML文档:
<SIGNATURE>
<HR/>
<COPYRIGHT>2001年</COPYRIGHT>
<BR/>
<EMAIL>webmaster@eastdajia.com </EMAIL>
<BR/>
<LAST_MODIFIED>2001年12月</LAST_MODIFIED>
</SIGNATURE>
选择:
使用竖线(|)而不是逗号来分开子元素,以便指明文档需要输入其中一个子元素。
例:
<!ELEMENT PAYMENT (CASH|CREDIT_CARD)>
对应的XML文档:
< PAYMENT >
<CASH>100 </CASH>
</ PAYMENT >
选择和序列的组合
例:
<!ELEMENT message (header, body ,(signature | footer))>
<!ELEMENT choice ((may | could) , (this | that))>
元素出现次数指示符(Element occurrence indicator)
--?字符
它说明元素可以出现0次或1次。
-- * 字符
它说明元素可以不出现,或出现1次或多次。
-- + 字符
它说明元素必须出现至少一次,或者说可以出现一到多次
如:
<!ELEMENT SCHOOL (SCHOOL_CITY, SCHOOL_NAME, STUDENT*)>
--混合型 Mixed
这表明该元素可以包含DTD中定义的其它任何元素、字符数据、实体等的任意组合。
这种类型的元素声明是:
<! ELEMENT anyelement (字符数据|子元素|实体)*>
例:
<!ELEMENT music (#PCDATA|name|singer)*>
则符合该定义的XML文档如:
<music>
<name>在那桃花盛开的地方</name>
<singer>蒋大为</singer>
一首流行二十多年的歌曲。
</music>
自然语言、半结构化数据、结构化数据
用户tk666说:棉袄质量真心不错,很厚实。孩子穿了挺暖和,款式也挺好看,上身效果不错,毛领还可以拆卸,满意。
<comment user=“tk666”>棉袄质量真心不错,很厚实。孩子穿了挺暖和,款式也挺好看,上身效果不错,毛领还可以拆卸,满意。</comment>
<comment user=“tk666”><item>棉袄</item>质量真心不错,很厚实。孩子穿了挺暖和,款式也挺好看,上身效果不错,毛领还可以拆卸,满意。</comment>
<comment user=“tk666”>
<item>棉袄</item>
<rating>满意</rating>
<content>质量真心不错,很厚实。孩子穿了挺暖和,款式也挺好看,上身效果不错,毛领还可以拆卸,满意。
</content>
</comment>
例子:
<?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>
对应的XML文档
<year format =“numeric”>2010</year>
声明属性时应注意以下几点:
属性名称遵循的规则与有效的元素名称相同。
在一个给定的元素中不能有两个属性同名。
若属性值中含有双引号,则该属性值应用单引号括起来。
属性的默认声明:
REQUIRED:必须具有该属性。
如:<!ATTLIST book isbn CDATA #REQUIRED>
IMPLIED:该属性不是必须使用的。
如: <!ATTLIST book isbn CDATA #IMPLIED>
FIXED:将一个属性声明为FIXED之后,在相应XML文档中可以不用明确地指定该属性的值,但如果要明确地指出属性值,该值必须是属性定义时给出的默认值。
属性缺省值紧跟在属性类型之后.
如: <!ATTLIST book isbn CDATA #FIXED “2312”>
属性的类型:
1.CDATA类型
属性值必须是字符串
<!ATTLIST film
class CDATA “action"
year CDATA #REQUIRED
>
2.Enumerated类型
从一组给定的值中选择一个作为其属性值
<!ATTLIST play position (center | forward | defenseman) “center”>
3.ID类型
每一个属性值在XML文档中必须是唯一的
<!ATTLIST film class ID #REQUIRED>
注:ID属性的取值,不能以数字开头。
4.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>
5.IDREFS类型
允许使用XML文档中多个元素的ID类型属性的值
<!ELEMENT bookInfo(publishiers,authors,books)>
<!ELEMENT publishers(publisher+)>
<!ELEMENT publisher(pname,address)>
<!ATTLIST publisher publisherID ID #REQUIRED>
……
<!ELEMENT author(aname,age,sex)>
<!ATTLIST author authorID ID #REQUIRED>
…….
<!ELEMENT books(book*)>
<!ELEMENT book(title,price,year)>
<!ATTLIST book publisher IDEF #REQUIRED author IDREFS #REQUIRED>
<?xml version="1.0"?>
<publisher publisherID="p001">
……
<author authorID="a001">
…
</author>
<author authorID="a002">
…
</author>
</authors>
<books>
<book publisher="p001" author="a001 a002">
6.NMTOKEN类型
属性值是一个有效XML名称记号,是CDATA的子集,属性值必须是英文字母、数字、句号、
破折号、下划线或冒号等,不能包含空格。
DTD定义:
<!ELEMENT paragraph (#PCDATA)>
<!ALLIST paragraph size NMTOKEN #REQUIRED>
对应的XML文件:
<paragraph size=“one_line”>…</paragraph>
<paragraph size=“two_lines ”>…</paragraph>
7.NMTOKENS类型
属性值是若干个有效XML数据的名称,以空格隔开
DTD定义:
<!ELEMENT paragraph (#PCDATA)>
<!ALLIST paragraph size NMTOKENS #REQUIRED>
对应的XML文件:
<paragraph size=“one_line two_lines”>…</paragraph>
8.ENTITY类型
将外部二进制数据文件或不可解析实体链接到XML中
<!ENTITY Grjl SYSTEM “罗纳尔多.txt”>
<!ELEMENT StartName (#PCDATA)>
<!ATTLIST StartName Life ENTITY #REQUIRED>
对应的XML文档
<StartName Life=“Grjl”>罗纳尔多</StartName>
9.ENTITIES类型
将多个外部二进制数据文件或不可解析实体链接到XML中
<!ENTITY Grjl1 SYSTEM “罗纳尔多1.txt”>
<!ENTITY Grjl2 SYSTEM “罗纳尔多2.txt”>
<!ELEMENT StartName (#PCDATA)>
<!ATTLIST StartName Life ENTITYS #REQUIRED>
对应的XML文档
<StartName Life=“Grjl1 Grjl2”>罗纳尔多</StartName>
10.NOTATION类型
XML 文档中引入了外部不可解析的实体后,解析器无法解析这些二进制文件,这时,
就可以使用NOTATION类型的属性为这些二进制文件指定与其对应的应用软件以对其进行处理。
<!NOTATION gif SYSTEM “image/gif”>
<!NOTATION jpg SYSTEM “image/jpg”>
<!NOTATION png SYSTEM “c://pic.exe”>
<!ELEMENT img EMPTY>
<!ATTLIST img type NOTATION #REQUIRED>
<img type=“gif”/>
例子:
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE 工程 [
<!ELEMENT 工程 (项目,负责人)>
<!ELEMENT 项目 (任务,负责部门)>
<!ATTLIST 项目 project_id ID #REQUIRED>
<!ELEMENT 任务 (#PCDATA)>
<!ELEMENT 负责部门 (#PCDATA)>
<!ATTLIST 负责部门 person_p_id IDREF #REQUIRED>
<!ELEMENT 负责人 (姓名,负责项目)>
<!ATTLIST 负责人 person_id ID #IMPLIED>
<!ELEMENT 姓名 (#PCDATA)>
<!ELEMENT 负责项目 (#PCDATA)>
<!ATTLIST 负责项目 project_project_id IDREF #REQUIRED>
]>
<工程>
<项目 project_id="p1">
<任务>赛平网的构建</任务>
<负责部门 person_p_id="c001" />
</项目>
<负责人 person_id="c001">
<姓名>李博</姓名>
<负责项目 project_project_id="p1" />
</负责人>
</工程>
条件语句
当创建DTD和XML文档时,有时会需要注释某些没有在XML文档中声明的DTD部分。使用注释是一种方法,还可以通过IGNORE指令封装某部分DTD的声明。
<!ENTITY % ignore "IGNORE">
<!ENTITY % include "INCLUDE">
<![%ignore;[
<!ELEMENT 图书馆A (科技类,文艺类,社科类)>
]]>
<![%include;[
<!ELEMENT 图书馆B (科技类,社科类,少儿类)>
]]>
<!ELEMENT 科技类 (#PCDATA) >
<!ELEMENT 文艺类 (#PCDATA) >
<!ELEMENT 社科类 (#PCDATA) >
<!ELEMENT 少儿类 (#PCDATA) >