1、第6章XML6.1 XML技术背景及其发展技术背景及其发展6.2 XML语法基础语法基础 6.3 DTD 6.4 XSL转换转换 6.5 XML解析解析 习题习题 6.1 XML技术背景及其发展技术背景及其发展SGML是一种通用的文档结构描述标记语言,主要用来定义文献模型的逻辑和物理类结构。随着Web应用的不断深入,Web标准化组织W3C推出了精简的SGML版本XML,作为下一代Web应用的数据传输和交互的工具。6.1.1 Web体系结构体系结构XML是eXtensible Markup Language的缩写,即可扩展标记语言,是一种可以用来创建自己的标记的标记语言。与SGML一样,XML也
2、是一个用来定义其他语言的元语言。XML和HTML都来自于SGML,都含有标记,有着相似的语法,但也有很多不同,最大区别在于:HTML是一个定型的标记语言,它用固有的标记来描述、显示网页内容,比如表示标题,有固定的尺寸;而XML则没有固定的标记,不能描述网页具体的外观,只是描述内容的数据形式和结构,实现数据和显示格式的分离。传统的Web应用程序是继承了传统的客户机/服务器(C/S)模式的软件体系结构,其交互过程如图6.1所示。图6.1 传统Web体系结构交互过程客户端程序是一个浏览器,充当着浏览者的代理角色。浏览器将对页面的请求发送给HTTP服务器,服务器会通过CGI脚本或JSP代码等来动态生成
3、HTML以回应请求。这种结构存在一些重要的限制:(1)用户被限制在了客户端浏览器上。(2)所有的内容都以HTML的形式传递。这就限制了客户端进行任何后期处理的能力,而且在传递时用户所能看到的也仅限于服务器应用程序决定的内容。(3)如果用户希望看到不同的显示方式,比如用图形替代表格,或者另一种排序方式,就必须再到服务器上请求一个新的响应。XML下的Web体系结构如图6.2所示。由于XML本身就是数据并且它可以转化为HTML,而且XML是层次结构的,很容易对非关系型数据进行编码,因此XML到HTML的转换不会影响到XML数据本身。这样,基于XML的Web体系结构可以使用简单的协议控制松散开放的资源
4、集合。所有这些都使得XML成为在服务器与服务器应用程序之间交换数据的最佳媒介。图6.2 XML下的Web体系结构6.1.2 XML应用应用目前,XML与HTML一起使用,扩展了Web页的能力,极大地丰富了Web页面展示和处理的内容。XML的应用使得Web页可以实现如下功能:(1)传递任意类型的文档。(2)可以使用其他方法排序、过滤、重新排列、查找以及管理信息。(3)显示高度结构化的信息。1XML解决方案解决方案XML的定义只由框架语法组成。当创建一个XML文档时,不必使用有限的预定义元素集,而可以创建自己的元素,并赋予任意名称。这就是扩展标记语言中术语“扩展”的意义。因此,可以使用XML描述从
5、音乐乐谱到数据库的任意类型的文档。【例6.1】描述书籍列表。Java编程技术 孙一林 机械工业出版社 410 42 C#深入详解 王寅永 电子工业出版社 509 44 注意:当描述一个数据库时,使用XML比使用专用格式(例如Access的.mdb和dBase的.dbf格式)多了两个好处:一是XML是可供人阅读的;二是它基于一种公共的开发标准。了解XML文档中的标记名称(例如本例中的“书籍清单”、“书籍”和“书名”)不是XML定义的一部分是很重要的。这些名称是创建某个文档时构造的。XML文档类似于树状分层结构,元素可以完全嵌套在另一个元素中,且只有单个顶层元素(在本例中是以“书籍清单”标记表示的
6、元素),即文档元素(Document Element)或根元素(Root Element)包含了所有其他元素。因此,可以很容易地使用XML定义分层结构文档。本例XML文档的结构如图6.3所示。图6.3 书籍列表文档结构图1)编写XML文档XML具有严格定义的语法。与HTML不同,每一个XML元素必须同时有一个起始标记和一个结束标记(或者一个特殊的空元素标记),任何被嵌套的元素必须完全包含在包围它的元素中。2)显示XML文档在HTML页中,浏览器知道H1标记是顶级的标题,并根据这一点格式化并予以显示。这样做是可能的,因为该标记是HTML标准的一部分。但是,浏览器和其他程序怎样得知如何处理和显示在
7、XML文档中用户创建的元素(例如示例文档中以“书籍”或“价格”标记表示的元素)呢?有以下三种基本方法可以通知浏览器(尤其是IE)如何处理和正确显示每一个XML元素:(1)样式表链接。样式表链接可以把一个样式表链接到XML文档。样式表是一个包含格式化每一种XML元素的指令的独立文件。样式表是使用级联样式表(CSS)或扩展样式表语言(eXtensible StyleSheet Language,即XSL)编写的。(2)数据绑定(Data Binding)。数据绑定需要创建一个HTML页,把XML文档链接到HTML上,并绑定该页面中的标准HTML标记(例如绑定SPAN或TABLE到XML元素),那么
8、HTML元素会自动显示绑定它们的XML元素的信息。(3)脚本(Scripting)。脚本可以创建一个HTML页,把一个XML文档链接到HTML上,并通过编写脚本代码(JavaScript或VBScript)来访问和显示每个XML元素。浏览器把XML文档处理为文档对象模型(Document Object Model,DOM),它提供了许多对象、属性和方法集,以便脚本代码可以访问、管理并显示XML元素。2XML应用技术应用技术常用的XML应用技术包含下面几种。1)DTD(Document Type Definition,文档类型定义)DTD是XML文档的可选组件。DTD类似一个数据库概要信息:定义
9、和命名了可以在文档中使用的元素、元素显示的顺序、可用的元素属性以及其他文档特性。要使用一个特定的XML应用,通常需要在XML文档中包含其DTD。在文档中包含DTD限制了可以使用的元素和结构,这样文档就被强制符合该应用程序的标准。本章前面的XML文档示例并不包括DTD。2)XML SchemaXML Schema本身就是采用标准XML语法来描述的,遵循XML规范,用于对XML文档的内容及其语义的约束机制进行有效的类型验证。XML Schema既可以描述那些有严格句法的文档(如XML文档),也可以描述那些强调概念及其相互间关系的文档(如关系数据库),提供了原始数据类型(包括byte、date、in
10、teger、sequence、SQL)以及Java中基本的数据类型,也允许用户定义新的类型。由于其功能更为强大,因此正逐步替代DTD。3)XSL(Extensible Stylesheet Language,扩展样式表语言)XSL允许使用XML语法创建功能强大的文档样式表,目的是将内容和显示格式分开,让不同的用户按照各自希望的格式显示同一XML文档的数据内容。XSL是专为XML设计的,可以把XML文档转换为HTML格式。XSL实际上是由两个基本点不同的标准转化语言(XSLT)和格式化对象(FO,定义如何显示结果树)构成的。4)XSLT(XSL Transformation)XSLT的基本原理是
11、模式和模板匹配,是根据XSL样式将一个XML文档转换到另一个XML文档的语言。其表达的转换本身也是用XML文档表示的,描述了将源树转换到结果树的转换规则。XSLT表达的转换也称为样式表(Stylesheet),样式表包含一系列模板规则(Template Rules),一个模板规则包含一个模式(pattern)和一个模板(template)。6.2 XML语法基础语法基础与HTML语言不同,XML遵循严格的语法规则,拥有更加灵活的特性,能够作为编写其他语言的元语言。本节将介绍XML的基本语法,以及如何创建XML文档。6.2.1 标记语法标记语法XML是基于文本的标记语言,标记是XML文档最基本的
12、组成部分。1标记标记XML标记(tag)负责提供和描述XML文件或数据包(XML实体)的内容结构。其结构与HTML基本相同,由界定内容的不同部分的标记组成。与HTML不同的是,几乎所有的XML标记都是对大小写敏感的,其中包括元素的标记名和属性值,例如DATE、Date、date均不相同。同时,XML标记分为非空标记和空标记两种。1)非空标记非空标记必须由开始标记与结束标记组成,两者之间是该标记的内容。开始标记以“”结束,中间是标记名称;结束标记以“”结束,中间是标记名称,如例6.2所示。【例6.2】XML文件。Java编程技术 孙一林 机械工业出版社 该XML文档中,“”和“”分别是开始标记和
13、结束标记,“Java编程技术”是标记的内容。注意:开始标记名称和结束标记名称大小写必须一致。2)空标记若仅仅是为了准确地指明文档中的特定位置而不提供一个包容器,或者将所有信息全部存储在属性中而不存储在内容中,那么就可以使用空标记。空标记以“”结束,如例6.3所示。【例6.3】空标记。或者2命名规则命名规则在XML文档中,元素、属性和一些其他结构的命名都必须以字母、下划线(_)或冒号(:)开头,其后跟随有效命名字符,中间不能有空格。而有效命名字符除了前面的内容外,还包括数字、连字符(-)、句点(.)。在实际应用中不应该使用冒号,除非是用作命名空间的分隔符。另外,字母并非局限于ASCII码,XML
14、还支持其他语言用在标记当中,如例6.4所示。【例6.4】XML标记命名。、都是正确的标记名。注意:最好采用标准的命名规范,而且应该使用具有描述性的名字,以方便阅读、理解。6.2.2 文档结构文档结构下面通过例6.5所示的一个完整的XML实例,来说明XML的文档结构。【例6.5】完整的XML文档。一个XML文档应由三部分组成:序言(可选的):序言位于XML文档的顶部。主体:由一个或多个元素组成,形式为一个可能包含有字符数据的层次树。尾部(可选的):包括注释、处理指令和/或紧跟元素树后面的空白。6.2.3 序言序言XML文档的序言包含了关于文档本身的元信息,而不是文档的内容。通常序言可以包含XML
15、声明、处理指令、注释、嵌入的DTD以及可扩展的样式表声明等。1XML声明声明XML文档通常都以一个XML声明开始,形式如下:如果XML中包含声明,就必须将声明置于文档中的第一行。任何内容都不能放在XML声明之前,即使是空格也不允许。XML声明中的“xml”必须为小写,其后还可以包含一些属性,这些属性提供关于版本、编码以及文档是否独立的信息。这些属性已经在XML 1.0规范中作了定义:(1)version:描述文档的版本号(目前版本号必须为“1.0”)。该属性用来保证对XML未来版本的支持,不能省略。(2)encoding:描述文档的文件编码。如果该属性省略,则默认为“UTF-8”编码;如果希望
16、支持中文,则可以设置为“gb2312”或“GBK”。(3)standalone:描述文档是否需要外部文件。该属性取值“yes”表示所有必需的实体声明都包含在文档中,取值“no”表示需要外部的DTD。XML声明中属性的顺序是有一定要求的,encoding属性必须出现在version属性之后,而standalone属性只能位于声明的最后。2处理指令处理指令处理指令(Processing Instruction,即PI)可以出现在XML文档中除标记之外的任何地方,但是一般出现在序言中。指令给XML解析器提供信息,使其能够正确解释文档内容。XML处理程序但不处理PI,而是将它们传递给应用程序。处理指令
17、的起始标识是“”,格式如下:其中,target是进行XML数据处理的应用的名称,instructions是一个字符串,包含了传给应用的信息和命令。【例6.6】通过处理指令指定XSL样式表的引用。使用处理指令存在着如下优点:作为脚本或服务器端包含文件的挂钩,可作为扩展模式的机制,也是一种无需改变DTD认证就可以扩展文档的方法。此外,处理指令也可以作为一种传递嵌入在文档当中的文档显示信息的途径,而且不会影响文档的结构。3注释注释注释以“”结束,可以是单独的一行,也可以是包含在标记“”之间的几行。XML处理器通常会忽略掉被注释的内容。注释格式如例6.7所示。【例6.7】正确的注释。注释可以出现在XM
18、L文档声明之后的任何地方,但是不能放在标记中,这样会破坏标记的完整性。同时不允许在注释中嵌套注释,并且注释中不能出现两个连字符,即“-”标记。错误的注释书写如例6.8所示。【例6.8】错误的注释书写。.some tag content./tag 4文档类型声明文档类型声明不能把文档类型声明(Document Type Declaration)同文档类型定义(Document Type Definition,也就是通常所说的DTD)相混淆。而且,文档类型声明中包含着文档类型定义的内部子集以及到外部子集的引用,即提供了关于XML文档内的元素和属性如何出现的规则,以确定哪些元素和属性是有效的,哪些是
19、必需和可选的。所有有效的XML文档必须包含文档类型声明,但简单的格式正规的文档并不需要这样的包含关系,而且它们也不包含任何实体引用。6.2.4 元素元素XML文档的第二个主要部分(主体)是文档元素或根元素。而元素是XML标记的基本组成部分,可以包含其他元素,如字符数据、字符引用、实体引用、PI、注释和/或CDATA部分这些合在一起被称做元素内容(Element Content)。所有的XML数据(除了注释、PI和空白外)都必须包容在其他元素中。在XML文档中,元素指出了文档的逻辑结构,并且包含了文档的信息内容。1元素与标记的不同元素与标记的不同XML中的标签(tag)和元素(element)很
20、类似,但实际上并不相同。元素描述的是一个开始标签和一个结束标签以及其中的内容;而标签则是元素的一部分,它以“”结束。图6.4表示一个包含标签的完整元素。图6.4 元素和标签2元素的分类元素的分类XML元素由开始标记、结束标记以及标记之间的数据构成。开始标记和结束标记用来描述标记之间的数据,这些数据是元素的值。元素的语法结构是:文本内容XML元素可以大致分为以下四类。1)空元素如果元素中不含任何文本,那么该元素是个空元素。【例6.9】空元素应用1。为了节省空间,XML指定空元素也可以用缩略形式表示,它是起始和结束标记的混合体,由一个元素类型名称紧跟一个反斜杠组成,并围在一对尖括号中,如例6.10
21、所示。它既简洁,而且还能明确指出该元素既不会有内容,也不允许有内容。【例6.10】空元素应用2。空元素和空标记形式类似。2)仅含文本的元素有些元素仅含文本内容,如例6.5中的“书名”、“作者”、“出版社”、“页数”、“价格”所表示的元素都是仅含文本的元素。3)仅含子元素的元素XML元素中还可以嵌套其他元素,可使相关信息构成等级结构。其中,容器元素称为父(元素),所包含的元素称为子(元素)。如例6.5中,“书籍”表示的元素只包含“书名”、“作者”、“出版社”、“页数”、“价格”所表示的元素,称为仅含子元素的元素。同样,“书籍清单”所表示的元素虽然是根元素,但由于只包含“书籍”表示的元素,因此也是
22、仅含子元素的元素。4)混合元素既含有子元素又含有文本的元素称为混合元素。如例6.11中,“书籍”表示的元素既包含“作者”、“出版社”、“页数”、“价格”所表示的元素,又包含文本“Java编程技术”,所以称为混合元素。【例6.11】混合元素应用。Java编程技术 孙一林 机械工业出版社 410 426.2.5 属性属性属性给元素提供进一步的说明信息,必须出现在起始标签中。XML元素可以拥有一个或多个属性。属性以名称、取值对出现,属性名不能重复,名称与取值之间用等号“=”分隔,并用引号(单引号、双引号均可)把取值引起来,如例6.12所示。【例6.12】属性应用。Java编程技术属性是元素数据的附加
23、信息,用来描述元素的一些特性,这些信息既可以存储在属性中,也可以存储在元素中,分别如例6.13和例6.14所示。【例6.13】作者作为属性。Java编程技术机械工业出版社【例6.14】作者作为元素。Java编程技术孙一林机械工业出版社6.2.6 特殊字符及特殊字符及CDATA1特殊字符特殊字符在XML文档中,开始和结束标记之间出现的所有合法字符都会被有效地传给XML处理程序。但是由于一些字符在XML文档中有特殊的含义,例如标记字符“”,如果直接查询或指定这些字符,解析器就会出错。为了避免把字符数据和标记中需要使用的一些特殊符号相混淆,当字符数据中需要使用这些特殊符号时,必须通过采用它的实体引用
24、来代替。实体引用必须以符号“&”开头,以符号“;”结尾。一些常用特殊字符的实体引用如表6.1所示。2CDATACDATA是用来包含文本的方法,结构如下:CDATA以“!CDATA”开始,以“”结束,方括号内为所要包含的文本的内容。对例6.15中C+程序使用CDATA表示如例6.16所示。【例6.15】包含特殊字符和文本的内容。#include main()int a10;cout“请输入10个整数!n”;for(int i=0;i10;i+)cinai;cout“下面是你输入的数据!n”;for(int i=0;iai;【例6.16】CDATA应用。C+C+是一种主流的面向对象语言。!CDAT
25、A#include main()int a10;cout“请输入10个整数!n”;for(int i=0;i10;i+)cinai;cout“下面是你输入的数据!n”;for(int i=0;iai;运行结果如图6.5所示,即对于C+程序的文本不作任何处理,原样输出。另外,在使用CDATA时,要注意三点:(1)CDATA必须大写;(2)CDATA不允许嵌套,即CDATA内不能再包含CDATA节;(3)CDATA的结束字符串“”和“”间不能有空格或者换行符。图6.5 CDATA在IE中的运行结果6.3 DTD6.3.1 DTD结构结构DTD作为一套关于标记符的语法规则,是用于保证XML文档格式正
26、确的有效方法。一个DTD文档包含元素的定义规则、元素间关系的定义规则、元素可使用的属性以及可使用的实体或符号规则等。为使DTD关联到XML文档,可以将DTD嵌入到XML文档内部,也可以在文档中添加对外部DTD的引用,还可以将二者结合起来使用。1内部内部DTD通常XML文档由序言和主体构成,使用内部DTD的方法是在XML文档的序言部分加入一个DTD描述,加入的位置是紧接在XML处理指令之后,只定义本文档,其语法格式为:!DOCTYPE 根元素名 XML主体部分处理指令中xml的属性standalone取值“yes”表明该文档未引用外部文档。“!DOCTYPE”是关键词,表示定义DTD;位于DOC
27、TYPE后的是XML文档中的根元素名;其后方括号“”和“”内为DTD正文,包含各元素和属性的定义。在XML文档中定义一个内部DTD如例6.17所示。【例6.17】内部DTD。!DOCTYPE 联系人列表 张弛 S001 A公司 (010)62345678 内部DTD由于处在XML文档内部,因此查看元素定义非常方便。2外部外部DTD外部DTD是后缀名为“.dtd”的基于文本的文档。如果在XML中使用外部DTD,则需要指明外部DTD的位置,其语法格式为:XML主体部分处理指令中xml的standalone属性的值为“no”,表明该XML需要引用外部DTD文档,同时在DOCTYPE声明中,应该加入S
28、YSTEM属性说明外部DTD文档的位置。对于例6.17的XML文档,使用外部DTD和XML文档定义如例6.18所示。【例6.18】外部DTD和XML文档。(1)DTD文件:link.dtd。(2)XML文件:link.xml。张弛 S001 A公司 (010)62345678 注意:DTD文档中若使用中文标记,需要将处理指令中的encoding指定为“gb2312”或者“GBK”编码;若使用英文标记,则可省略处理指令。6.3.2 元素声明元素声明文档类型声明不仅定义文档中每个可能存在的元素,还定义元素的类型和取值。XML元素既可以为空,也可以是纯文本或含有若干个子元素,子元素同时可以有各自的子
29、元素。DTD通过元素之间的父子关系描述整个文档的结构关系。1元素类型声明元素类型声明元素声明的语法格式如下:其中:ELEMENT:关键字,表示该声明为元素类型声明。元素名:文档根元素下所包含的子元素名称,在DTD中通常称为基本标识符。Type:元素内容类型,位于元素名称后,可分为五种类型Empty(空)、子元素型、混合型、ANY(任意类型)和#PCDATA。2元素内容类型元素内容类型1)Empty用于声明空元素,该元素不包含任何内容。声明空元素语法如下:【例6.19】DTD中定义br空元素。当然,如果br需要含有信息,可通过添加属性来实现。【例6.20】XML中应用br元素。或2)子元素型元素
30、只包含一系列子元素,不包含字符或者混合内容。其语法格式如下:其中,ContentModel表示子标记和容器标记的关系。【例6.21】DTD中定义联系人列表为子元素型。表示XML文档中联系人列表元素中包含联系人元素。根据子元素之间的关系,子元素内容模型可以有两种结构:序列和选择。下面根据几个例子加以说明。【例6.22】DTD中定义地址为子元素型。表示在地址元素中包含三个子元素且各子元素之间要用“,”隔开。三个子元素分别是街道、城市、省份,而且根据声明,子元素只可能遵循例6.23中的顺序出现。【例6.23】XML中应用地址元素。长安南路 西安 陕西【例6.24】DTD中定义联系方式为子元素型。表示
31、联系方式元素可以选择其使用的子元素,可选的子元素用“|”隔开。在这个例子中,联系方式可以包含子元素电话或EMAIL,但是不能同时包含这两项。【例6.25】XML中应用联系方式元素。(010)62345678或 子元素内容模型还可以互相嵌套使用,如例6.26所示。【例6.26】DTD中定义联系人为子元素型。根据以上声明可知,联系人必须包含五个元素:姓名、编号、公司、地址以及电话或EMAIL,且它们必须按照指定的顺序出现。除了子元素之间的关系产生的不同结构外,元素出现的频率即出现的次数也可以通过使用如下可选字符来指定:(1)+:表示元素可以出现一次或者多次。(2)*:表示元素可以出现零次或者多次。
32、(3)?:表示元素可以出现零次或者一次。【例6.27】DTD中定义联系人为子元素型(定义元素出现频率)。表示在XML文档中EMAIL可出现1个或多个,而电话可出现0个或多个,地址要么不出现,要么只出现一个。3)混合型混合型内容说明元素可以包含子元素又可以包含文本数据。其语法格式如下:【例6.28】DTD中定义联系人为混合型元素。注意:#PCDATA(表示文本)必须首先指定,而且括号内各项以“|”隔开,括号外必须有“*”,表示是可以重复的。【例6.29】XML中应用联系人元素。张弛 S001 A公司 (010)62345678由于定义时括号内各项必须以“|”隔开,因此编号(或公司、EMAIL、电
33、话)可以不出现,同时联系人元素包含“张弛”文本。4)#PCDATAPCDATA(Parsed Character Data),表示被解析的字符数据。声明为#PCDATA类型的元素是不包含其他任何元素,而只包含字符数据(数字、字母和符号等)的元素。其语法格式为:【例6.30】DTD中定义电话为#PCDATA型元素。【例6.31】XML中应用电话元素。(010)62345678或010-623456785)ANY声明类型为ANY的元素实质上没有结构,它可以包含字符数据、任何声明的元素类型或混合类型。其语法格式如下:【例6.32】DTD中定义编号为ANY型元素。【例6.33】XML中应用编号为Emp
34、ty型。或:【例6.34】XML中应用编号为子元素型。A公司(010)62345678【例6.35】XML中应用编号为混合型。S001 A公司【例6.36】XML中应用编号为#PCDATA型。这是编号信息6.3.3 定义属性定义属性属性是对元素的补充和修饰,用来描述元素的额外信息。属性由“=”分割开的属性名和属性值对构成,出现在元素标记的内部。通过属性,可以给元素绑定大量信息。1声明语法声明语法在DTD中,属性是使用ATTLIST标记声明的。对于含属性的元素,至少要通过一个ATTLIST标记声明其属性列表。声明由以下三部分构成:ATTLIST关键字、属性修饰的元素名称以及零个或多个属性定义。为
35、了增强可读性,每个属性定义通常占一行。属性声明的语法格式为:其中,属性默认值设置如表6.2所示。属性类型如表6.3所示。2属性类型属性类型1)CDATACDATA表示文本字符串,是最常用的属性类型。它表示可以包含任何字符串,但不允许使用“”、“&”等特殊字符,而允许使用代表它们的实体引用(如<、>等)。【例6.37】DTD中定义姓名的属性性别为CDATA类型。【例6.38】XML中应用姓名的属性性别。张弛2)枚举属性发枚举声明的属性可能有一组值,即属性的取值包含在预定义的字符串列表内,属性必须从该组值中选定一值作为属性值。这些属性值包含在圆括号内,并以“”隔开。【例6.39】DTD
36、中定义姓名的属性性别为枚举类型。【例6.40】XML中应用姓名的属性性别。张弛注意:在DTD中定义时,属性默认值为“男”,需要引号,而()内以“”隔开的可选值不需引号。在XML中属性性别的取值只能取DTD中定义的“男”或“女”,不能取其他值。3)ID对于ID类型的属性,属性值是具有唯一标识功能的名称,而且必须遵守XML名称定义的规则。由于元素的ID属性值在整个文档中必须是唯一的,因此经常用来作为元素的唯一标识符。如果要设置元素的某个属性为ID类型,则该属性必须设置为#IMPLIED或#REQUIRED,不能是#FIXED或缺省的。可想而知,如果为ID提供缺省值,特别是固定的缺省值是毫无意义的,
37、这会破坏ID的唯一性。【例6.41】DTD中定义姓名的属性编号为ID类型。【例6.42】XML中应用姓名的属性编号。张弛刘强注意:使用ID类型时,属性值遵守XML命名规定,所以属性值不能以数字开头,必须以字母或者下划线开头。本例中姓名为张弛和刘强的编号必须是不同的,同时要求其编号在整个文档中是唯一的。4)IDREF如何使ID类型的属性发挥作用呢?那就得通过引用。通过使用IDREF类型可以在两个对象之间建立一对一的关系。IDREF值必须和文档中某个ID类型的值相同,即表示引用某个ID类型的值。在应用程序中,通过ID和IDREF可实现交叉引用,而不必多次重复整个元素。【例6.43】DTD中定义姓名
38、的属性办公地址为IDREF类型,引用公司的地址属性值。【例6.44】XML中应用姓名的属性办公地址。A公司张弛B公司刘强5)IDREFSIDREFS可以理解为IDREF的复数形式。该类型的属性包含一个XML名称列表,名称间用空白间隔且每个名称都是文档中某个元素的ID,即将一个元素与其他多个元素相关联。例6.45】DTD中定义公司的属性成员为IDREFS类型,引用员工的编号属性值。!DOCTYPE 公司 张弛刘强周丽6)ENTITY实体可以用于属性声明中,它能够重用公共的结构,提高代码效率。对于一个可能多次出现的结构,可以声明代表该结构的实体,然后通过引用实体实现对结构的调用。另外,实体中可以包
39、含未解析内容,并作为有效的属性值。通过这种方式,文档创作者可以引用各种类型的数据,而不仅仅是XML标记。如果有一个图形文件并希望将它作为图解,可以借助实体将它插入文档。【例6.46】DTD中定义照片的属性来源为ENTITY类型。!DOCTYPE 公司 张弛7)ENTITIESENTITIES类型像IDREFS类型一样也可以理解为ENTITY的复数形式。ENTITIES类型的属性包含在DTD的其他位置声明的多个未解析实体名称中,其间用空格隔开。每个实体名称引用一个外部的非XML数据源。【例6.47】DTD中定义照片的属性来源为ENTITIES类型。!DOCTYPE 公司 张弛 8)NMTOKEN
40、NMTOKEN(Name Token)类型属性值是一个XML名称记号。NMTOKEN和CDATA非常类似,不同之处在于它是CDATA的一个子集,支持使用的字符必须是字母、数字、句点、连字符、下划线或冒号。【例6.48】DTD中定义员工的属性电话为NMTOKEN类型。!DOCTYPE 公司 张弛9)NMTOKENSNMTOKENS类型属性允许包含一个或多个用空格分割的NMTOKEN类型。【例6.49】DTD中定义员工的属性电话为NMTOKENS类型。!DOCTYPE 公司 张弛3属性默认值属性默认值在DTD的属性声明语法结构中,每个ATTLIST声明除属性类型外,属性默认值也是必不可少的。一般提
41、供如下四种属性的默认值:(1)#REQUIRED。#REQUIRED指定该属性是元素必有的。(2)#IMPLIED。#IMPLIED指定该元素可以选择是否包含某属性。(3)#FIXED。#FIXED格式为#FIXED+默认值。在将一个属性声明为FIXED之后,在相应的XML文档中可以不用明确指定该属性的值,处理器就会自动地给出其值;但如果要明确地指出属性值,该值必须是属性定义时给出的默认值。(4)默认值。如果元素中不包含该属性的属性值,解析器会将默认值作为属性值,否则该属性可以有其他属性值。6.3.4 实体的声明和引用实体的声明和引用XML提供了声明内容块的方法,可以根据需要多次引用声明的内容
42、块,如此不仅能够节省空间,而且能够减少文档创作者的代码量。为了在DTD中声明实体,需要定义实体的名称及它引用的内容,使用时通过名称来进行引用。1预定义实体预定义实体XML必须保留某些字符用于本身格式的定义,如尖括号等。鉴于此,XML提供了一些预定义的实体,来表示某些特殊字符。引用预定义实体的具体方法是在符号“”之后加上数字值和分号。例如,大于号可以表示为“>”或“>”。对于使用频率极高的字符,XML提供了预定义的实体(参见表6.1)。2普通实体普通实体普通实体是能够声明与某个名称相关联的可解析的文本块,可通过该名称引用相应的文本。这类实体声明包含关键字ENTITY、实体名称和
43、替换值。1)内部普通实体内部普通实体将需要替换的内容在DTD内部说明,定义格式如下:【例6.50】内部普通实体应用。利用例6.50中的声明,只需引用名称“&code;”,就能够在文档内容的任何位置插入“(029)”,引用方法为在实体名之前加符号“&”,在其后加分号。2)外部普通实体通用实体也有外部形式,即将置换文本存放在外部文件中,其定义格式如下。其中,关键字SYSTEM用于指示外部源,URL表示文件的位置。【例6.51】外部普通实体应用。!DOCTYPE 公司列表&company;其中要引用的URL为“公司名.txt”,其内容如下:International Business Machine
44、通过“&company;”实体引用文本文件的内容,即为“International Business Machine”。外部普通实体也可以使用PUBLIC关键字、URI标识符和后备的URL组合来定义。6.3.5 DTD的不足的不足目前,DTD是W3C推荐的验证XML文档有效性的正式规范,它极大地推动了XML的发展。然而随着XML的发展,DTD也逐渐暴露出很多不足。首先,DTD过于复杂,并且采用非XML语法规则,不能用XML工具进行操作处理;其次,DTD对数据类型定义支持不够,所定义的数据类型有限,并且都是针对属性而设立的,无法满足电子商务等Web应用所需要的丰富数据类型;再者,DTD扩展机制复
45、杂,也很脆弱,最大的弊病在于不能表达元素之间的相互关系,同时DTD也不支持名称空间机制。以上种种缺陷,促使W3C组织致力于寻求一种新的机制来取代DTD。在众多的标准之中,以Microsoft公司提出的XML Schema较为引人注目。它具有完全符合XML语法、丰富的数据类型、良好的可扩展性以及易被DOM等XML解析器处理等优点。6.4 XSL转换转换6.4.1 XSL简介简介XSL转换格式语言XSLT,负责将XML源代码转换为另一种格式;Xpath,是一种定义XML部分或模式的语言;XSL格式化对象(Formatting Object,即FO),是一种定义XML显示方式的语言。1工作原理工作原
46、理浏览器打开XML文档(见例6.1)时,会将XML数据解析为如图6.3所示的树状结构。从该树状结构中,可以确定各个节点的位置以及路径,如节点的路径是“书籍清单书籍作者”。如果XML文档中存在对XSLT文档的引用,浏览器会打开该样式表文档并将其应用到上述结构树中。浏览器遍历源文件,尝试将XSLT文档中的模式与XML数据文档中的特定元素(即节点)匹配,当发现匹配的内容时,浏览器把相应的匹配模板应用到这些元素,并根据模板中的规则输出数据。模板可能包含操纵数据的命令和(或)应用格式的HTML标记。结果是一个输出树,反映了模板所作的更改以及为了更改文件的格式而添加的HTML标记。然后浏览器解析输出树,并
47、根据HTML指令将其显示出来。2XSL样式表样式表下面通过一个例子来说明XSL的样式结构。首先,建立名为book.xml的XML文档,内容如例6.1,并增加一条处理指令:该指令用于在XML文档中引用XSL样式表,其中“href”表示引入表所在的位置和文件名。如果文档与样式表在同一文件夹下,只要给出文件的名字即可(如本例),否则就需要给出这个文件的完整路径。“type”表示该XML文档所使用的类型。然后,创建XSL文档book.xsl,如例6.52所示。【例6.52】book.xsl文档。简单例子 书名:作者:出版社:最后,用浏览器打开book.xml,结果如图6.6所示。图6.6 通过XSL转
48、化后显示结果再来看XSL文档,由于样式表本身就是个XML文档,因此文档以一个xml声明开始:第二行语句:其中,xsl:stylesheet标记定义了样式表的开始,是XSL样式表的根元素。这里需要注意的是,XSL样式表的根元素的名称必须是“stylesheet”。如果让浏览器的XSL的处理器处理XSL变换,根元素必须有命名空间,并且命名空间的名字必须是“http:/www.w3.org/TR/WD-xsl”。第三行语句:其中,xsl:template标记定义了一个模板的开始,模板属性match=“/”将模板和XML文档的根元素(/)匹配起来。关于模板内容后面将详细介绍。XSL文档最后两行分别定义
49、了模板的结束和样式表的结束。由此可以得出,任何一个结构完整的XSL样式单都具有如下结构:6.4.2 模板模板模板(Template)是XSLT中最重要的概念之一,任何一个XSLT文档至少包含一个模板。模板的概念就像是搭积木,也可以将模板看做程序中的方法、类或者模块。模板由两部分组成:模板匹配和模板调用。1模板匹配模板匹配模板匹配定义XML源文档中哪一个节点将被模板处理,其语法格式如下:其中,xsl:template用于定义一个新模板。属性中name、priority和mode用来区别匹配同一节点的不同模板,但它们不是常用的属性。match属性用来定位XML源文档中哪一个节点被模板处理。整个定位
50、过程中最先匹配的是树的根节点,根节点用“/”表示,然后匹配其他节点。此时,只要在引号中指明要处理的元素名称即可。如果在引号中出现的是“*”,那么表示该规则适用于所有的未单独指定处理的元素节点。此外,XSL中还可以使用路径指示符来指定一些特殊位置的元素与模板相匹配。一个路径指示符是“/”,表示直接的父子节点关系,如“书籍清单/书籍/书名”,表示匹配“书籍清单下的元素。“/”代表任意深度位置,如用来匹配文档中任何位置的元素。而如果是,则表明是匹配元素的后继节点中所有元素。很显然,某些树节点在XSL中可能会对应多个模板,在这种情况下,只有最后一个对应模板会生效。2模板调用模板调用模板调用定义输出的格