第三章XML文档类型定义.docx
- 文档编号:26435502
- 上传时间:2023-06-19
- 格式:DOCX
- 页数:74
- 大小:346.39KB
第三章XML文档类型定义.docx
《第三章XML文档类型定义.docx》由会员分享,可在线阅读,更多相关《第三章XML文档类型定义.docx(74页珍藏版)》请在冰豆网上搜索。
第三章XML文档类型定义
第三章XML文档类型定义
一个XML文档如果需要符合有效性的要求,则它必须遵照一定的文档类型说明,本章主要介绍XML文档的类型定义,包括文档类型定义的基本格式,元素声明,属性声明和实体声明。
通过对本章的学习,可以掌握文档类型定义的基本内容、基本方法和具体结构。
3.1文档类型定义
文档类型定义(DocumentTypeDefinition,简称DTD)是一类用于定义XML文档具体格式的文本,它规定XML文档的数据结构,提供元素、属性的相关控制信息。
一个XML文档只有符合指定的DTD文档才能称之为一个有效的XML文档。
3.1.1内部DTD
内部文档类型定义(internalDTD)用于与特定XML文档相关联,它必须位于这个XML文档中,它规定了文档的数据组织方式,文档必须按照该DTD的约束进行标记才能成为一篇具备有效性的文档,否则就算XML文档是良构的,但是只要它的组织方式不是依照内部DTD的要求,则也不能满足有效性的要求。
下面给出一个简单的内部DTD例子,并且由于IE6.0不能对XML的有效性进行检查,我们这里使用了AltovaXMLSpy2005来对例子进行有效性检查。
例3-1-1-1:
程序3-1-1-1
文件3-1-1-1.xml
xmlversion="1.0"encoding="UTF-8"?
>
--ThisDTDisabouttheinformationoffriends-->
DOCTYPEFriendsInfo[
--FriendsInfoistherootelement-->
ELEMENTFriendsInfo(friendA,friendB)>
ELEMENTfriendA(ID,name,age,sex,city,remark)>
ELEMENTfriendB(ID,name,age,sex,city,remark)>
ELEMENTID(#PCDATA)>
ELEMENTname(#PCDATA)>
ELEMENTage(#PCDATA)>
ELEMENTsex(#PCDATA)>
ELEMENTcity(#PCDATA)>
ELEMENTremark(#PCDATA)>
]>
--thatistheendofDTD-->
--XMLdatabegin-->
Guangzhou
aprettygirl
--friendAandfriendBisnotthesametypeofelement-->
Guangzhou
图3-1是AltovaXMLSpy2005,以后简称XMLSpy对例子3-1-1-1的有效性验证,如果例子里面没有内部DTD的话,XMLSpy会指出一个“不能在该文挡实例中定位对一个支持schema类型(DTD,W3cSchema)的引用”的错误。
图3-1例3-1-1-1的有效性检查
这个内部DTD定义了XML文档必须以FriendsInfo作为文档元素,并且FriendsInfo包含了两个子元素friendA和friendB,这两个子元素又包含了6个子元素,分别是ID、name、age、sex、city和remark。
DTD下面的文档内容必须严格按照这种嵌套形式进行标记,否则文档就不具备有效性,下列这些情况都是违反内部DTD的:
Ø如果在
Ø如果如果在
Ø如果先出现
Ø如果在
Ø如果
Ø如果ID、name、age、sex、city和remark没有按照DTD中声明的前后顺序排列,例如出现
Ø如果标记名与DTD中定义的标记名不同,例如DTD中定义的ID,而在下面的数据部分变成了
内部DTD的声明一定要位于文档的XML声明之后和第一个元素之前。
并且DOCTYPE和ELEMENT等关键字都需要是大写的形式。
DOCTYPE用于指定文挡元素,所有的关于DTD的声明都必须位于“
DOCTYPEdocument-element[”和“]>”之间。
ELEMENT用于声明元素,指出元素的结构。
3.1.2外部DTD
从前面我们可以看到,如果每个XML文档要具备有效性就必须与一定的DTD文档相联系,但是如果每个XML文档都使用内部DTD的话,我们每创建一个文档相应的就需要编写一次DTD,这显然很不科学,也对以后管理和维护XML文档造成困难。
因此,需要有一种机制,它可以使得多个XML文档可以共用一个文档类型定义,我们可以使用外部DTD(ExternalDTD)文件来达到这个目标。
外部DTD有两种类型,第一种是私有型DTD,第二种是公共型的。
我们先看看私有型DTD的例子。
例3-1-2-1,是例子3-1-1-1的外部DTD形式,首先是外部DTD文件:
程序3-1-2-1
文件:
3-1-2-1.dtd
xmlversion="1.0"encoding="UTF-8"?
>
--Thisisthedtddocumentof3-1-2-1.xml-->
ELEMENTFriendsInfo(friendA,friendB)>
ELEMENTfriendA(ID,name,age,sex,city,remark)>
ELEMENTfriendB(ID,name,age,sex,city,remark)>
ELEMENTID(#PCDATA)>
ELEMENTname(#PCDATA)>
ELEMENTage(#PCDATA)>
ELEMENTsex(#PCDATA)>
ELEMENTcity(#PCDATA)>
ELEMENTremark(#PCDATA)>
接下来是XML文件:
程序3-1-2-1
文件:
3-1-2-1.xml
xmlversion="1.0"encoding="UTF-8"?
>
--Thisisthe3-1-2-1.xmlfile-->
DOCTYPEFriendsInfoSYSTEM"3-1-2-1.dtd">
--friendAandfriendBisnotthesametypeofelement-->
在
DOCTYPEFriendsInfoSYSTEM"3-1-2-1.dtd">中多了SYSTEM这个关键字,它指明了该DTD是一个私有的文档,是可在该作者或组织所编写的多个XML文件中通用的DTD。
引用私有外部DTD的形式是:
DOCTYPEdocument-elementSYSTEM“URI-of-dtd”>
引号内的必须填写具体的外部DTD的位置信息,它是一个URI(UniformResourceIdentifier)统一资源标示符,提供了一个在全世界范围内的站点和资源名称的唯一地址。
如果与一个XML文档相关联的外部DTD文件也位于XML文档所在目录中,则此时URL可以变为文件名称,否则就需要给出外部DTD文件的绝对路径。
例如例子3-1-2-1,它的XML文档与外部DTD文件是位于同一目录的,所以它可以使用"3-1-2-1.dtd"的形式来说明DTD文件的位置,否则,如果假设XML文档位于E:
\下面,而dtd位于E:
\source\目录下,则需要变成”E:
\source\3-1-2-1.dtd”的形式才能通过XMLSpy的有效性验证。
一般,由于一个DTD总是提供给多个XML文档使用,因而推荐通过指定外部DTD的URL来使用该DTD,从而避免需要在每个用到该DTD的目录中都保留该DTD文件的复本。
例3-1-2-2给出一个公共型的外部DTD例子:
xmlversion="1.0"encoding="UTF-8"?
>
DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.0Transitional//EN""http:
//www.w3.org/TR/REC-html40/loose.dtd">
helloworld!
公共型外部文档类型定义的格式是:
DOCTYPEdocument-elementPUBLIC“name-of-dtd”“URI-of-dtd”>
公共型的DTD使用关键字PUBLIC,它是一种由权威机构制订的,提供给特定行业或公众使用的DTD。
声明时,还需要指定DTD的名称,它有一定的格式:
“前缀//DTD拥有者//DTD描述//语言种类”
DTD名称的命名规则和XML文件的命名规则稍有不同,DTD名称只能包含字母、数字、空格和符号:
“_%$#@()+:
=/!
*;?
”。
而且前缀部分只能出现下面三种名称的一种:
ØISO:
表示ISO标准的DTD
Ø+:
表示被改进的非ISO标准的DTD
Ø-:
未被改进的非ISO标准的DTD
由于本书的例子只是为了让读者了解XML的原理知识,因此以后一般举例用到的DTD文件都是私有型的。
3.1.3内部和外部DTD的混合使用
如果多个XML文档之间存在着一部分相同的数据描述,相互间也存在部分不同的数据描述时,则如果仅仅是简单的想套用某一个外部DTD文件的做法就不能解决问题,而且在一个XML文档中,文档声明“
DOCTYPE…>”语句只能出现一次,这也就意味着我们不可能采用上面两种方法的简单叠加来解决问题。
那么如何把内部DTD和外部DTD相结合呢?
解决的方法就是“求同存异”——尽量的将各个XML文档中相似的结构汇聚到外部DTD中进行定义,然后再针对每个文档的特点定义内部DTD。
具体的形式是:
DOCTYPEdocument-elementSYSTEM“URI-of-dtd”[
internalDTD
]>
例3-1-3-1:
例子总共有三个文件构成,一个dtd文件,两个XML文件。
程序3-1-3-1
文件1:
3-1-3-1.xml
xmlversion="1.0"encoding="UTF-8"?
>
DOCTYPEfriendsInfoSYSTEM"3-1-3-1.dtd"[
ELEMENTcareer(#PCDATA)>
ATTLISTcareer
studentCDATA#REQUIRED
>
]>
student
第二个XML文件:
程序3-1-3-1
文件3-1-3-1a.xml
xmlversion="1.0"encoding="UTF-8"?
>
DOCTYPEfriendsInfoSYSTEM"3-1-3-1.dtd"[
ELEMENTcareer(#PCDATA)>
ATTLISTcareer
managerCDATA#REQUIRED
>
]>
最后一个是DTD文件:
程序3-1-3-1
文件3-1-3-1.dtd
xmlversion="1.0"encoding="gb2312"?
>
ELEMENTfriendsInfo(friend)>
ELEMENTfriend(id,name,age,sex,address,career)>
ELEMENTid(#PCDATA)>
ATTLISTid
nicknameCDATA#IMPLIED
>
ELEMENTname(#PCDATA)>
ELEMENTage(#PCDATA)>
ELEMENTsex(#PCDATA)>
ELEMENTaddress(#PCDATA)>
在例子中,两个文件3-1-3-1.xml和3-1-3-1a.xml共享一个外部DTD文件,这个DTD文件定义了绝大部分两个XML文档都具备的数据结构,比较两个XML文档的数据部分,会发现在元素career部分存在不同的属性,因此在XML文档中又各自定义了一个内部DTD。
需要注意的是在外部DTD定义过的元素就不能再在内部DTD中重新定义,否则就会引起混乱。
3.2元素声明
前面我们从总体上介绍了如何将文档类型定义与具体的XML文档相关联,接下来我们进一步阐述如何进行元素声明。
3.2.1元素类型声明
元素类型声明规定了元素的数据内容,设置了在一个文档中究竟能够出现什么类型的元素、出现几次、出现的顺序、每个元素如何取值和如何嵌套子元素等。
元素类型声明的格式是:
ELEMENTnametype>
例如我们从前面的dtd文件中摘抄几个:
ELEMENTfriendsInfo(friend)>
ELEMENTname(#PCDATA)>
ELEMENTfriend(id,name,age,sex,address,career)>
注意ELEMENT一定要大写,并且一定要遵守元素类型声明中规定的元素如何组织的规则。
例如在
ELEMENTfriendsInfo(friend)>中规定了它仅能包括一个子元素friend,因此不能出现两个以上的friend子元素。
又如
ELEMENTfriend(id,name,age,sex,address,career)>规定了元素friend只能有id,name,age,sex,address,career这六个子元素,因此不能出现另外的子元素,并且这六个子元素的排列顺序也一定要按照元素声明中出现的先后顺序进行排列,否则也是不符合元素声明的。
3.2.2#PCDATA
在元素的类型声明中,如果声明的数据类型是#PCDATA,则表示该元素的内容是可析的字符数据,不能在元素中包含子元素。
例3-2-2-1:
程序3-2-2-1
文件3-2-2-1.xml
xmlversion="1.0"encoding="UTF-8"?
>
--ThisisanarticleaboutCarnegieMellonUniversity-->
DOCTYPEarticle[
ELEMENTarticle(title,content)>
ELEMENTtitle(#PCDATA)>
ELEMENTcontent(#PCDATA)>
]>
CarnegieMellonUniversity
Hands-onexperienceisakeypartoflifeatCarnegieMellon,saysMichaelSteidel,directorofadmissions.The1,360studentsinthefreshmanclassapplytooneoftheschool'12programs;computerscience,engineeringanddramaaremostpopular.
Theschooltakesprideinbeingonthecuttingedgeineveryfieldandencouragesstudentstothinkaboutapplyingwhattheylearntotherealworld."Westartworkingwithstudentsasfreshmentogetthemthinkingaboutwhat'spossibleintermsofwhatyoureducationcando,"Steidelsays.
Thatapproachseemstobepayingoffbothinthenumberofapplications(they'vemorethandoubledinthelastdecade)andinthevalueofaCarnegieMellondegree:
about70percentofstudentshaveajobofferwhentheygraduate(anadditional30percentgorighttograduateschool).
这是一篇对英语短文进行标记的XML文档,文档是对美国卡内基梅隆大学的一些介绍,我们希望XML处理器对于短文内容不要进行任何的解释而将其作为一个整体来对待,因此需要在DTD中指明短文的内容是#PCDATA数据类型。
本例使用的是内部DTD的方式。
例3-2-2-2:
程序3-2-2-2
文件3-2-2-2.xml
xmlversion="1.0"encoding="UTF-8"?
>
--ThisisanarticleaboutCarnegieMellonUniversity-->
DOCTYPEarticle[
ELEMENTarticle(title,content)>
ELEMENTtitle(#PCDATA)>
ELEMENTcontent(#PCDATA)>
]>
--thisisaerrorexamplebecause:
-->
--useaPIinthe#PCDATA-->
xmlversion="1.0"?
>
worddocument="test2.doc?
>
这是一个错误的例子,虽然我们的本意是想让例子2-1-1-2的XML文档作为例子3-2-2-2的文章内容,让它介于
但是由于#PCDATA类型是不能包含子元素的,也就意味着元素content里面不能出现标记符号“<”和“>”,而XML处理器在处理:
xmlversion="1.0"?
>
worddocument="test2.doc?
>
视为是在元素content中包含了处理指令和子元素,违反了#PCDATA是不可解释的字符数据的规定而报出错误。
图3-2显示了XMLSpy的错误报告:
图3-2例3-2-2-2的显示结果
如果将:
xmlversion="1.0"?
>
worddocument="test2.doc?
>
改成:
<?
xmlversion="1.0"?
>
<?
worddocument="test2.doc?
>
<test>
</test>
则可以通过XMLSpy的检查,如图3-3所示:
图3-3例3-2-2的修正结果
3.2.3空元素(EMPTY)
前面我们提到过空元素,它不包含任何不析的字符数据,也不包含子元素,那么相应的我们如何在一个DTD中来说明一个元素是空的呢?
具体的形式是:
ELEMENTelement-nameEMPTY>
注意EMPTY一定要大写,它表明该元素是一个空元素。
例3-2-3-1给出一个示范例子:
程序3-2-3-1
文件3-2-3-1.xml
xmlversion="1.0"encoding="UTF-8"?
>
DOCTYPEroot[
EL
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第三章 XML文档类型定义 第三 XML 文档 类型 定义