欢迎光临
免费的PDF电子书下载网站

XML技术应用(第二版) PDF下载

编辑推荐

1.主要内容包括XML概述、XML语法、文档类型定义、文档对象模型、XSL转换、XML中的链接、命名空间、XML Schema以及Web Services。2.附录A介绍了简单易用的XML集成开发环境XML SPY的安装及使用, 附录B介绍了一组由Java语言提供的针对XML的API。3.以XML 1.0版本为基础,语言简洁、内容丰富、涵盖面广,并且包含丰富的实例程序。4.面向XML的初学者,避开XML的高级应用,从*简单、*基础的内容入手,使读者牢牢掌握基本知识,这样再学习和研究高级应用就会容易得多。 ;

内容简介

本书从XML的基本概念开始,结合具体代码示例,由浅入深地介绍了XML基础应用,以及结合XML的相关技术的应用。 本书共分为9章。首先介绍了XML的基本概念和语法,接着介绍了用来约束XML文档的两种规范: 文档类型定义和XML SChema,然后介绍了如何利用文档对象模型来访问XML文档以及如何利用可扩展样式语言来转化XML文档,*后介绍了其他一些基于XML的应用技术,包括XQuery、XLink、XPointer、XML Web Services。 本书可作为高等院校计算机相关专业的参考书,也可供相关专业技术人员和教育工作者查阅使用。

作者简介

暂无

XML技术应用(第二版) PDF下载

目录

目录

 ;

第1章XML概述

 ;

1.1XML的概念

 ;

1.1.1标记语言

 ;

1.1.2XML的起源

 ;

1.2XML的特性和优点

 ;

1.2.1XML的特性

 ;

1.2.2XML的优点

 ;

1.3XML的处理过程

 ;

1.4XML的设计目标

 ;

1.5XML的相关技术

 ;

1.6创建并显示简单的XML文档

 ;

1.6.1Hello XML World

 ;

1.6.2显示XML文档

 ;

本章小结

 ;

思考题

 ;

第2章XML语法

 ;

2.1XML文档结构

 ;

2.1.1序言区

 ;

2.1.2主体区

 ;

2.1.3尾声区

 ;

2.2元素和标记

 ;

2.2.1元素的命名

 ;

2.2.2标记

 ;

2.2.3空元素

 ;

2.2.4元素的嵌套

 ;

2.3属性

 ;

2.3.1属性的命名

 ;

2.3.2属性的值

 ;

2.4引用

 ;

2.4.1实体引用

 ;

2.4.2字符引用

 ;

2.5处理指令

 ;

2.6注释

 ;

2.7CDATA节

 ;

2.8创建格式良好的XML文档

 ;

2.8.1XML文档的声明

 ;

2.8.2元素

 ;

2.8.3属性

 ;

2.8.4其他

 ;

2.8.5文档全文

 ;

本章小结

 ;

思考题

 ;

第3章文档类型定义

 ;

3.1DTD的概念

 ;

3.2DTD的调用

 ;

3.2.1内部DTD的声明

 ;

3.2.2外部DTD的声明

 ;

3.2.3内部DTD和外部DTD的联合使用

 ;

3.3DTD的结构

 ;

3.4元素的声明

 ;

3.4.1#PCDATA

 ;

3.4.2空元素

 ;

3.4.3子元素

 ;

3.4.4混合型

 ;

3.4.5ANY

 ;

3.5实体的声明

 ;

3.5.1内部一般实体

 ;

3.5.2外部一般实体

 ;

3.5.3内部参数实体

 ;

3.5.4外部参数实体

 ;

3.6属性的声明

 ;

3.6.1设置属性的类型

 ;

3.6.2属性的默认设置

 ;

本章小结

 ;

思考题

 ;

第4章命名空间和XML Schema

 ;

4.1命名空间的概念

 ;

4.2命名空间的语法

 ;

4.2.1定义命名空间

 ;

4.2.2多个命名空间

 ;

4.2.3属性

 ;

4.2.4默认命名空间

 ;

4.3命名空间的有效性

 ;

4.4XML Schema与DTD

 ;

4.5XML Schema有效性检验

 ;

4.6XML Schema语法

 ;

4.6.1简单类型

 ;

4.6.2复杂类型

 ;

4.6.3xsd:any元素和xsd:anyAttribute元素

 ;

4.6.4数据类型

 ;

4.6.5文档举例

 ;

本章小结

 ;

思考题

 ;

第5章文档对象模型

 ;

5.1DOM概述

 ;

5.1.1DOM的概念

 ;

5.1.2DOM的结构

 ;

5.1.3DOM的工作方式

 ;

5.1.4DOM的规范

 ;

5.1.5正确理解DOM

 ;

5.2DOM API

 ;

5.2.1DOM API的概念

 ;

5.2.2DOM接口继承树

 ;

5.2.3DOM API核心接口

 ;

5.3利用DOM API处理结构化文档

 ;

5.3.1遍历XML文档

 ;

5.3.2处理结点

 ;

5.4DOM的简单应用

 ;

5.4.1Java XML解析器

 

5.4.2遍历文档

 

5.4.3添加结点

 

5.4.4删除结点

 

5.4.5替换结点

 

本章小结

 

思考题

 

第6章可扩展的样式语言

 

6.1XSL的概念

 

6.2XSLT概述

 

6.2.1转换语言

 

6.2.2树状结构

 

6.2.3XSLT文档

 

6.3XSLT模板

 

6.3.1xsl:stylesheet元素、xsl:template元素和match属性

 

6.3.2xsl:applytemplates元素、xsl:valueof元素和select属性

 

6.3.3xsl:foreach元素

 

6.4XSLT匹配结点的模式

 

6.4.1匹配根结点、子结点及其他后代结点

 

6.4.2匹配元素名称

 

6.4.3通配符

 

6.4.4使用ID匹配单个元素

 

6.4.5使用@匹配属性结点

 

6.4.6使用comments()匹配注释结点

 

6.4.7使用processinginstruction()匹配处理指令结点

 

6.4.8使用text()匹配文本结点

 

6.4.9使用或操作符

 

6.4.10使用[]进行测试

 

6.5XSLT输出

 

6.5.1属性值模板

 

6.5.2xsl:element元素

 

6.5.3xsl:attribute元素和xsl:attributeset元素

 

6.5.4xsl:processinginstruction元素

 

6.5.5xsl:comment元素

 

6.5.6xsl:text元素

 

6.5.7xsl:copy元素

 

6.5.8xsl:number元素

 

6.5.9xsl:sort元素

 

6.5.10xsl:variable元素

 

6.5.11xsl:if元素和xsl:choose元素

 

6.5.12xsl:calltemplate元素

 

6.5.13xsl:output元素

 

6.6XSLT合并样式表

 

6.7XPath简介

 

6.7.1XPath表达式

 

6.7.2XPath结点轴

 

6.7.3XPath表达式类型

 

6.7.4XPath路径定位举例

 

6.8XSLFO简介

 

6.8.1XSLFO区域

 

6.8.2XSLFO主要元素

 

本章小结

 

思考题

 

第7章XQuery查询语言

 

7.1XQuery概述

 

7.1.1XQuery与XPath、XSLT的关系

 

7.1.2XQuery示例

 

7.2XQuery常用表达式

 

7.2.1基本表达式

 

7.2.2算术表达式

 

7.2.3比较表达式

 

7.2.4逻辑表达式

 

7.2.5序列表达式

 

7.2.6条件表达式

 

7.2.7量词表达式

 

7.2.8FLWOR表达式

 

7.3XQuery其他语法

 

7.3.1命名空间声明

 

7.3.2变量声明

 

7.3.3函数声明

 

7.4XQuery更新功能

 

7.4.1插入表达式

 

7.4.2删除表达式

 

7.4.3替换表达式

 

7.4.4更名表达式

 

7.4.5转换表达式

 

本章小结

 

思考题

 

第8章在XML中使用链接

 

8.1XML中的链接

 

8.2XLink概述

 

8.2.1XLink的概念

 

8.2.2XLink的设计原则

 

8.3链接元素

 

8.3.1简单链接

 

8.3.2链接行为

 

8.3.3扩展链接

 

8.3.4弧元素

 

8.3.5行外链接

 

8.4XPointer概述

 

8.5使用XPointer访问信息

 

本章小结

 

思考题

 

第9章XML Web Services

 

9.1Web Services概述

 

9.1.1Web Services发展历程

 

9.1.2Web Services的特点

 

9.1.3Web Services体系结构

 

9.1.4Web Services协议

 

9.2WSDL

 

9.2.1WSDL结构

 

9.2.2WSDL主要元素

 

9.2.3WSDL示例

 

9.2.4WSDL绑定类型

 

9.3SOAP

 

9.3.1SOAP简介

 

9.3.2SOAP设计目标

 

9.3.3SOAP示例

 

9.3.4SOAP消息交换模式

 

9.3.5SOAP消息

 

9.3.6SOAP编码规则

 

9.3.7HTTP上的SOAP

 

9.3.8在RPC中使用SOAP

 

9.4UDDI

 

本章小结

 

思考题

 

附录AXMLSpy简介

附录BXML的Java API

参考文献

 

媒体评论

评论

前沿

前言

毫无疑问,21世纪是Web的时代。随着Internet的飞速发展,各种新技术应运而生。标记语言特别是HTML的出现改变了计算机的发展方向,以文档对象为基础、以浏览器为载体、内容更丰富更具实时性的图形界面取代了单调的命令行界面,没有任何网络基础的普通用户也可以通过鼠标点击而轻松地阅读新闻和收发邮件。然而,HTML本身却存在着很多缺陷。首先,HTML是一种样式语言,目前在Internet中扮演的只是数据表示的角色,随着信息量的增多,HTML变得越来越难以胜任。其次,HTML对浏览器的过度依赖也形成了HTML标准的严重不统一,从而导致许多信息表示只能由某种特定的浏览器来解释,HTML的这些不足使得人们重新思考HTML在Internet上的角色,并开始研究一门新的语言来弥补HTML的缺陷,XML的产生正是这种思考的最终结果。XML是一种专门为Internet所设计的标记语言,它的重点是管理数据本身,数据的表示形式交给其他的技术来解决。这种明确的分工带来了更高效的程序设计、更快速的搜索引擎、更统一的数据表示方式及更方便的数据交流。XML是一种定义语言的语言,它克服了HTML的缺点,给了程序员更自由的空间。近几年,XML在除数据表示以外的其他方面也得到越来越广泛的应用。从数据存储到数据交换再到系统整合,XML都发挥着强大的作用。基于XML的新技术也如雨后春笋般层出不穷,Web Services、AJAX等技术相继形成,并逐渐发展成熟。W3C(万维网联盟)也不断为XML制定新的标准,并对其进行完善。因此,作为计算机相关专业的学生,了解并掌握XML是十分必要的。本书面向XML的初学者,避开XML的高级应用,从最简单、最基础的内容入手,使读者对基础知识牢牢掌握,这样再学习和研究高级应用就会容易得多。全书共分为9章。第1章从标记语言入手,引出XML的概念和相关技术,并介绍如何创建一个最简单的XML文档。第2章重点介绍XML语法,并学习如何创建格式良好的XML文档。第3章介绍文档类型定义(DTD),DTD可以详细说明允许或者不允许哪些元素出现在文档中,以及这些元素的确切内容和结构。在第3章中,读者将学习如何定义元素、实体和属性,如何将DTD附加到文档上,如何使用DTD验证文档的正确性以及如何编写自己的DTD来解决遇到的问题。第4章介绍命名空间和XML Schema,命名空间可以解决名称冲突的问题,而Schema则弥补了DTD的一些不足。第5章介绍文档对象模型(DOM),DOM提供了一系列接口,使应用程序可以方便地访问XML文档。第6章为可扩展的样式语言(XSL),XSL是比CSS更复杂、更强大的样式语言,XSL转换是XSL的一种,它可以将XML树状结构转化为其他形式的树状结构。第7章介绍XQuery查询语言,能够方便地从XML文档中提取需要的信息。第8章介绍XLink和XPointer,XLink提供多方向的超文本链接,XPointer不仅可以链接到特定文档,还可以链接到特定文档的特定部分。第9章介绍XML Web Services的思想和框架,并引出WSDL与SOAP。第2~7章为本书的重点,应该着重掌握。由于时间仓促,本书不足之处恳请读者批评指正。编者2017年1月

免费在线读

第3章文档类型定义

第1章已对文档类型定义(DTD)进行了简单的介绍,本章将详细介绍DTD。XML是一种元标记语言,人们可以使用这种语言自由地创建属于自己的标记集。但是在实际的应用中,如果所有的人都试图用自己定义的那一套标记来发布XML文档,那样最终导致的结果是谁也无法有效地获得信息,这就好比不同国家的人用自己的语言进行交流一样,结果必然是彼此都无法理解,这样违背了XML的设计初衷。因此在实际的应用中,除了要设计格式良好(wellformed)的XML文档以外,还需要定义文档的格式规则来明确文档的格式。DTD正是用来实现这一功能的。在资料自动化传输的过程中,其中一方的XML解析器可以根据DTD来确认所收到的资料格式是否准确无误,如果格式不对可以返回,让另一方重新传输文件,这一过程被称为合法性检验。经过合法性检验的文档不仅是一个格式正确的文档,而且是一个合法有效的文档。本章主要内容包括DTD的概念、DTD的调用、DTD的元素声明、属性声明及实体声明等。3.1DTD的概念DTD是文档类型定义的英文缩写,包含在文档类型声明中,它定义了某种文档类型的所有规则。简单来说,DTD的作用就是定义允许哪些或者不允许哪些内容在文档中出现。在DTD中,用户可以控制文档类型的所有元素、属性及实体等格式。如果一个XML文档的语法符合DTD的规定,那么它就是一个合法有效的XML文档。一个DTD可以在XML文档中直接定义,也可以独立定义在一个DTD文档中,用于被其他的XML文档调用。前者称为内部DTD,后者称为外部DTD。下面举一个简单的DTD实例。首先来看一个XML文档。







FC Barcelona



Spain



Neymar



这样的一个XML文档只能称为格式良好的文档,下面为这个文档编写一个DTD。打开记事本,在其中输入如下代码。







Age CDATA #REQUIRED
Sex (Male | Female) "Male">

将文件保存为以dtd为扩展名的文档,如Teams.dtd。这里简单解释一下该DTD文档的含义。在这个DTD文档中用于定义元素内容模式。例如“”表示了根元素Teams有且只有一个子元素Team,而且这个子元素在其父元素Teams中可以出现0到多次。“”表示元素Team有且只有3个子元素TeamName、Country、Member,而且这3个子元素在Team中出现的顺序不可颠倒,其中TeamName和Country子元素只能出现一次,Member子元素至少要出现一次。表示元素TeamName的内容只能是可解析的文本。“”用于定义元素的属性内容模式。在本例中的这一行代码就定义了元素Member有两个属性。Age属性的内容为非标记文本(CDATA),而且Age属性必须包含在元素中(#REQUIRED); Sex属性的内容从“Male”和“Female”中选择,并且规定了其默认值为“Male”。现在读者应该已经对DTD已经有了一个初步印象,下面介绍如何使用和设计DTD。3.2DTD的调用要利用DTD来校验XML文档的合格性,就必须把XML文档同DTD文件关联起来,这种关联就是DTD的调用。DTD的调用也称为文档类型声明,文档类型声明用于指定文档使用什么样的DTD。它出现在文档的序言区,在XML的声明之后,在其他所有的基本元素之前。文档类型声明的书写格式如下: 

中间省略号部分就是对DTD的调用。文档类型声明有两种方式: 内部DTD的声明及外部DTD的声明。3.2.1内部DTD的声明所谓内部DTD的声明,就是指DTD定义语言包含在XML文档中的声明方式。实际上就是将DTD定义语言的详细内容书写在XML的文档类型声明中。内部DTD声明的格式如下: 


]>

其中包含在[、]中间的省略号就是DTD定义语句。下面来看一个内部DTD声明的示例,该文档的名称为InTeam.xml。



]>

FC Barcelona

上面的XML文档就是一个内部DTD声明的示例,在这里利用XMLSpy来检验这个文档是否合法,检查的结果如图31所示。

图31InTeam.xml文档的合法性检验结果

图31表示这个XML文档是一个合法的文档。该文档在浏览器中的显示结果如图32所示。

图32InTeam.xml文档在浏览器中的显示结果

值得注意的是,正规的DTD声明中要求文档类型名必须与根元素名一致,否则合法性检验过程中会出现语法错误的提示,这一点在外部DTD的声明中也一样。如果将上述的XML文档稍作修改,写成如下的形式: 



]>

FC Barcelona

现在这个文档的文档类型名为Teams,而根元素名为Team,这时再对这个文档进行合法性检验,结果如图33所示。

图33文档类型名与根元素不一致的合法性检验结果

3.2.2外部DTD的声明外部DTD的声明就是在XML文档中引用已经编写好的独立的DTD文件。在已经存在标准的DTD文件的情况下比较适合使用这种声明方式,此时用户不需要为XML文档编写专门的DTD文件。外部DTD的声明格式如下。

其中“SYSTEM|PUBLIC”为可选的参数,是用于指定DTD文件源的关键字; DTD位置是DTD的URI,当DTD文件通过URI直接定位时,可以是文件的绝对地址,也可以是文件的相对地址,在后面将会进行详细的解释。接下来看一个外部DTD声明的示例,该文档的名称为OutTeam.xml。


FC Barcelona

在这个文档的DTD声明中引用了Team.dtd这个外部文档,下面就是这个文档的具体内容。


该文档在浏览器中的显示结果与内部DTD声明的文档显示结果相同,如图34所示。

图34OutTeam.xml文档在浏览器中的显示结果

一般情况下,外部DTD更加灵活。在外部DTD声明中不仅包含常规的关键字和根元素名称,而且包含指示外部DTD源的关键字和DTD的位置。用于指示外部DTD源的关键字有两个: SYSTEM和PUBLIC。如果使用SYSTEM关键字,解析器仅根据给出的DTD位置寻找DTD文件,这时DTD文件通过URI直接进行定位。在本例中,位于SYSTEM关键字之后的内容就是用于指定DTD文件相对位置的URI。此外需要注意的是,用于定位DTD的URI不应该包含段标识符(字符#加名称)。如果URI中包含该标识符,解析器将产生错误提示。如果DTD源关键字为PUBLIC,那么使用的情况就会稍显复杂。与SYSTEM关键字不同,PUBLIC用于声明众所周知的DTD词汇表。它可以是国际上的一些标准DTD,也可以是用户自己定义的DTD。不管怎样,有一点是相同的,就是这些DTD在使用的时候是作为公共的DTD来使用。因为这种DTD文件的“众所周知”(PUBLIC)性,用户在设计XML文档的时候,可以设想需要这些DTD对XML文档进行解析的应用程序客户端本地存在这样的DTD,那么在调用这些DTD时就不需要从Web服务器上远程下载。这时,用户就可以用PUBLIC关键字和URI帮助应用程序使用自己的算法定位需要的DTD文件。URI可以是URL,也可以是单独的名称。对上面的OutTeam.xml文件稍作修改如下。


FC Barcelona

可以发现,与SYSTEM关键字相比,PUBLIC关键字后面多了一个Team,这个参数为DTD的名称,其作用就是用于标志一个公共DTD,这样应用程序在处理这个XML文档时,先根据DTD的名称在本地的DTD文件库中查找该DTD,看是否存在该DTD文件,如果没有,再根据后面一个参数指定的路径查找DTD文件。实际上,如果该DTD文件存在于应用程序本地,可以不用编写后面的一个参数。但是公共DTD文件的“众所周知”性是相对的,因此建议在使用PUBLIC关键字时,一并在后面加上路径参数。3.2.3内部DTD和外部DTD的联合使用实际上在DTD使用的过程中,一般很少出现独立使用内部DTD和外部DTD的情况。对于独立使用内部DTD声明这种方式,如果XML文档的内容非常庞大,那么在内部进行DTD的声明将使得XML文档的内容变得臃肿,文档结构变得不太合理; 对于独立使用外部DTD声明这种方式,因为很少使用完全标准的DTD,当XML文档的结果发生细微变化时,则需要重新书写新的DTD文件。因此,在实际的应用过程中,通常是由XML文档的设计团队提供一份公共的DTD文件作为外部DTD,然后每个成员根据实际需要,通过内部DTD的声明扩展DTD的定义。如果内部DTD和外部DTD在标记定义或文档结构定义等方面发生冲突,以内部DTD的定义为准。下面举一个内部DTD和外部DTD联合使用的例子,即在外部DTD的声明之后,直接用中括号括起内部DTD的声明。







Age CDATA #REQUIRED
Sex (Male | Female) "Male">
]>





FC Barcelona



Spain



Neymar




3.3DTD的结构前面已经讲述了什么是DTD以及如何调用DTD,本节阐述本章的核心内容——DTD的结构。 DTD一般由元素声明、属性声明、实体声明等构成,但一个DTD文件并非都要用到这些内容,以前面的Teams.dtd为例。







Age CDATA #REQUIRED
Sex (Male | Female) "Male">

在这个DTD文件中,只包含了元素声明和属性声明,没有包含实体声明,这对Teams.xml文件已经足够。下面对这几类声明进行详细的介绍。3.4元素的声明元素是XML的核心与灵魂。在DTD中,元素类型是通过ELEMENT标记声明的。除了关键字,标记还提供所声明类型的名称和内容规范。在合法的XML文档中出现的每一项标记,都必须是已经在DTD的元素声明中定义的。元素的内容可以分为可解析的文本(#PCDATA)、空元素、子元素、任意内容及混合型内容等几大类,元素声明的一般语法如下。

其中#PCDATA表示元素的内容只能是可解析的文本数据; EMPTY和ANY是XML的保留字,分别表示空元素和任意元素内容; 子元素表示元素的内部只能是子元素; 混合型内容表示元素的内部可以是可解析的文本数据,也可以是子元素,甚至是两者的结合。详细内容如表31所示。

表31元素内容说明及其含义

元素内容说明含义#PCDATA表示元素的内容只能是可解析的文本数据EMPTY表示元素为空元素,但是元素中可以包含属性ANY表示元素的内容为任意的内容,可以是空元素、可解析文本数据、子元素、混合型元素中的任意一种子元素表示元素的内容只能是指定顺序和出现次数的子元素混合型内容表示元素的内部可以是可解析的文本数据,也可以是子元素,甚至是两者的结合
3.4.1#PCDATA#PCDATA表示元素的内容只能是可解析的文本数据,其使用的语法如下。

下面通过示例来说明这种标记的使用方法(为了方便说明问题,在后面的示例中对DTD的声明都采用了内部声明的方式)。【例3.1】#PCDATA内容






]>



FC Barcelona



Spain



Neymar


在XMLSpy中对这个XML进行合法性检验,如图35所示。

图35例3.1的合法性检验结果

可以知道,这样的XML文档是合法的,对上述示例进行细微修改,得出新文档如下。【例3.2】包含标记的#PCDATA






]>




FC Barcelona



Spain

Barcelona




Neymar


比较例3.1和例3.2可以发现,元素Country的内容由原先的Spain变成了Spain

Barcelona
,元素的内容中出现了标记,再对这个文件进行合法性检验,结果如图36所示。

图36例3.2的合法性检验结果

可以看到,XMLSpy提示元素Country的内容中不允许出现元素City。说明经过修改的XML文档不是一个合法的文档,因为在#PCDATA型元素的内容中出现了标记。3.4.2空元素所谓空元素,就是元素的内容为空的元素。一般来说,空元素只有起始标记,没有结束标记,在结束部分有一个/。很多情况下定义一个空元素是非常有用的,在HTML中也经常使用空元素,如元素就是一个空元素。与HTML不同的是,在XML中必须要用/>将元素标记写成闭合的形式。在DTD中,空元素的声明格式如下。

下面来看一个空元素的示例。





Age CDATA #REQUIRED
Sex (Male | Female) "Male">
]>



FC Barcelona



Spain




Member元素就是一个空元素。在实际应用中,空元素往往是附加属性的,有关属性的声明将在下面的章节中介绍。3.4.3子元素子元素内容规定了在元素中只能出现指定的子元素,而不能出现字符等其他内容。需要注意的是,这里进行子元素内容的声明只是针对该父元素,对该父元素的子元素的内容并不具有约束力。因此,其子元素中出现的内容需要根据子元素的元素声明而定。定义元素的子元素内容就是规定该元素中可以出现什么子元素,子元素出现的顺序,子元素出现的次数以及选择出现何种子元素,语法如下。

如果需要对子元素出现的次数进行限定,就可以在子元素名的后面加上一个通配符来规定元素出现的次数。在DTD中用于限定元素出现次数的通配符有3个,分别是“?”、*及 。如果把不加通配符也看作一种修饰方式,那么规定元素出现次数的修饰方式可以分为4种,具体修饰方式和含义如表32所示。

表32元素出现次数修饰方式及说明

后缀通配符含义(无) 表示元素出现且仅出现1次(1)?表示元素可以出现0或1次(0~1)*表示元素可以出现0到多次(0~n) 表示元素必须出现1或多次(1~n)
下面以之前提到的Teams.dtd文档来举例说明。






Age CDATA #REQUIRED
Sex (Male | Female) "Male">

以及“”定义语句就是用于声明元素的子元素内容的。前面一句规定了元素Teams只允许包含子元素Team,并且Team子元素在根元素Teams中出现的次数可以为0到多次。后面一句规定了元素Team中只允许包含TeamName、Country、Member 3个子元素,而且这3个子元素出现的顺序不能发生变化,只能按照定义语句中的顺序排列; 这个语句还规定了元素出现的次数,其中TeamName、Country元素出现且仅出现一次,而Member元素必须出现一或多次。一个合法的实例如例3.3所示。【例3.3】合法子元素






FC Barcelona



Spain



Neymar




如果修改XML文档Team元素内部子元素的出现顺序,如下所示。






Spain



FC Barcelona



Neymar




对该文档进行合法性检验,结果如图37所示。
可以发现,该文档无法通过合法性检验,原因就是在Team元素中,子元素出现的顺序不符合DTD定义语句的顺序。对该文档再次进行修改,如下所示。






FC Barcelona



Neymar




图37顺序发生变化的例3.3合法性检验的结果

对该文档进行合法性检验,结果如图38所示。

图38缺少Country元素的例3.3合法性检验的结果

可以发现,该文档也无法通过合法性检验,原因就是元素Member的位置应该是元素Country。DTD中规定要出现的子元素,在引用它的XML文档中必须出现。接下来继续对例3.3进行修改,如下所示。






FC Barcelona



Spain



Neymar



Messi




对该文档进行合法性检验,结果如图39所示。

图39增加了一个Member子元素的例3.3合法性检验的结果

可以看到,虽然增加了一个Member子元素,但是还是通过了合法性检验,因为在DTD中规定了Member子元素必须出现一或多次,所以两个Member子元素是允许的。对于其他两个通配符“?”和*,读者不妨自己进行测试和验证。在上述的内容中对子元素内容进行了一般的定义,包括子元素的名称、出现的顺序以及出现的次数等。在某些情况下,仅使用这些规定还不够。例如,需要在几个子元素中选择出现其中一个,而且这几个子元素不能同时出现,那么就需要使用专门的语法进行定义。其格式如下。

以球员的个人联系方式为例,假设只需要球员的电话或者是Email中的一项,那么在DTD文件中应当定义如下。



将文件保存为Member.dtd,对应的XML文档如下。




12345678


当然,在元素Member中的Tel子元素也可以替换成Email子元素。如果在XML文档中同时出现了Tel和Email子元素,那么将无法通过合法性检验。因为Tel和Email子元素同时在Member元素中出现,违背了DTD的规定。如果既希望在Tel和Email子元素中选择出现其中一个,又希望一个球员可以有多个的电话号码和Email地址,则只需要对前面的DTD文件稍作修改如下。




这样就可以允许在满足不同时出现Tel和Email子元素的情况下,有多个电话号码和Email地址。以上的情况是电话号码、Email地址两种联系方式不能同时出现。在有些情况下,希望一个球员既有电话号码,又有Email地址,而且这两个内容必须作为一个有机的整体出现,即电话号码必须与Email地址一一对应。这时只定义Tel以及Email两个子元素是不够的,需要用特殊的语法进行控制,其格式如下。

同样在括号后面可以加后缀通配符,以刚才的Member.dtd文件为例,对其稍作修改如下。




这个DTD文件的含义就是Member元素中必须同时出现Tel和Email子元素多次,或者不出现Tel和Email子元素,对Member.xml文档进行修改如下,以便说明这个含义。文档Member1.xml: 




12345678



aaa@fcbarcelona.com


文档Member2.xml: 




12345678



aaa@fcbarcelona.com



23456789



bbb@fcbarcelona.com


文档Member3.xml: 



上述3个文档都是合法的,下面再看其他几个示例。文档Member4.xml: 




12345678


文档Member5.xml: 




aaa@fcbarcelona.com



12345678


文档Member6.xml: 




12345678



23456789



aaa@fcbarcelona.com



bbb@fcbarcelona.com


这3个文档都是不合法的。因为Member4.xml对应的DTD中规定了Tel和Email子元素必须同时出现在Member元素中; Member5.xml对应的DTD中规定了Tel和Email子元素出现的顺序; Member5.xml对应的DTD中规定了Tel和Email子元素在Member元素中必须一一对应并作为一个整体出现。3.4.4混合型所谓混合型元素内容的声明,就是指元素的内容中可以出现可解析的文本数据,也可以出现子元素。混合型元素内容的声明方式如下。

同样在括号后面可以加后缀通配符来修饰。接下来通过例3.4来介绍混合型的元素内容声明。对前面的Member.xml文件进行修改如下,请注意其中Member元素是混合型。【例3.4】混合型元素






]>



Neymar





23456789







ccc@fcbarcelona.com




该文档是合法的。Member元素的内容可以是可解析的文本数据,也可以是其他子元素。但是这种元素声明方式不太严谨,与DTD设计的初衷不相符合,因此在实际的应用中应当尽量避免使用这种声明方式。3.4.5ANYANY内容声明表示元素内容中可以出现上述的4种内容: 可解析的文本数据、空元素、子元素内容、混合型元素内容。ANY是一种更不严格的元素声明方式,它严重违背了DTD的设计初衷,因此建议尽量避免使用这种声明方式。3.5实体的声明实体是指存储了符合一定规则的XML文档片段的单元,简单而言就是一段代码或者是一段数据的简写。例如,在XML中,使用“<”、“>”、“”、“"e;”、“&”这5个预定义的实体引用来代替文本<、>、“”、“"”、&字符,这些实体引用可以不加声明直接使用。实体根据其所处位置不同可以分为内部实体和外部实体。所谓内部实体,就是在文档内部定义的实体; 外部实体就是在文档外部定义的由文档实体通过URI来引用的实体。实体还可以分为一般实体和参数实体。所谓一般实体,就是DTD中定义的可以在XML文档中使用的实体; 参数实体就是在DTD中定义但是只能在DTD内部使用的实体。实体的声明在DTD的声明中进行。下面详细介绍这几类实体。3.5.1内部一般实体内部一般实体是指在XML文档内部定义的并且可以在XML文档中使用的实体,这种实体通常是一段代码的缩写。内部一般实体的定义语法和引用语法如下。定义语法: 

引用语法: 

&实体名;

注意: 在引用语法中,在实体名后面的“;”必须加上,否则就会出现语法错误。接下来通过例3.5来介绍内部一般实体的声明。【例3.5】内部一般实体







]>



Neymar



&Tel;



&Email;


例3.5文档在浏览器中的显示结果如图310所示。

图310例3.5在浏览器中的显示结果

可以看到,在XML文档中的“&Tel;”及“&Email;”已经被预先定义的12345678和aaa@fcbarcelona.com所替代,实体的引用成功。内部一般实体除了可以在XML文档的基本元素中引用外,还可以在DTD的内部引用,在DTD内部引用要注意以下3点。(1) DTD内部对实体的引用一般只能用于另外一个实体的定义中,但不能用于元素的声明中。(2) 内部一般实体无须先定义后引用。(3) 由于内部一般实体无须先定义后引用,因此在一个实体定义中引用另外一个实体时,要避免重复引用而造成引用的死循环。下面举例来说明这些问题。【例3.6】内部一般实体的DTD引用









]>




Neymar



&Tel;



&Email;


可以注意到,在例3.6的DTD声明中,对实体Mail进行了定义并且进行了引用,而且在引用实体Mail之前并没有对其进行定义。这个文档是合法的,该文档在浏览器中的显示结果如图311所示。

图311例3.6在浏览器中的显示结果

现在可以知道,在DTD中可以引用内部的一般实体。那么,如果将内部一般实体的引用用于DTD元素的声明会如何呢?【例3.7】元素声明非法使用内部一般实体









]>



Neymar



&Tel;



&Email;


该文档的合法性检验结果如图312所示。
对于重复引用造成死循环,如例3.8所示。【例3.8】重复引用内部一般实体








]>



Neymar



&Tel;



&Email;


图312例3.7合法性检验的结果

该文档在进行合法性检验的时候也会出错,检验的结果如图313所示。

图313例3.8合法性检验的结果

3.5.2外部一般实体外部一般实体是指实体是在XML文档外部定义,然后通过URI在文档内部进行引用。外部一般实体的定义和引用语法如下。定义语法: 

引用语法: 

&实体名;

接下来通过例3.9来说明如何定义和引用外部一般实体。【例3.9】外部一般实体









]>


&Content;

文件Content.txt的内容如下。


Neymar


&Tel;


&Email;

在例3.9中,“”就是一个外部一般实体的声明。这个文档是合法的,检验结果如图314所示。
与内部一般实体一样,在外部一般实体的声明中,也可以在DTD中对外部一般实体进行定义并同时加以引用。这种方式需要注意的几个问题同内部一般实体一样,这里不再赘述。下面通过例3.10来看一下外部一般实体在DTD中的应用。

图314例3.9合法性检验的结果

【例3.10】外部一般实体的DTD引用








]>



Neymar



&Tel;



&Email;


文件Content.txt的内容如下。

aaa@fcbarcelona.com

例3.10合法性检验的结果如图315所示。

图315例3.10文档合法性检验的结果

它在浏览器中的显示结果如图316所示。

图316例3.10在浏览器中的显示结果

值得注意的是,图316中的Email没有显示具体内容,这是因为现在绝大多数浏览器从安全性、方便性等方面考虑,默认不再支持在XML文档中调用外部实体。但是,从XML语法的角度,这种使用方式是没有问题的。3.5.3内部参数实体内部参数实体是指在DTD中定义的并且在只能在DTD中引用的实体。这种实体不能在XML文档的基本元素中使用,而且只能在外部DTD中定义才能在DTD中被引用。其定义和引用的语法如下。定义语法: 

引用语法: 

%实体名;

下面举例来说明内部参数实体的应用。【例3.11】内部参数实体




Neymar



12345678



aaa@fcbarcelona.com


文件Entity.dtd中的代码如下。






例3.11在浏览器中的显示结果如图317所示。

图317例3.11在浏览器中的显示结果

对于参数实体的声明需要注意以下两点。(1) 参数实体必须在外部DTD中定义才能用于元素的定义。(2) 参数实体的应用必须先定义后使用。这一点同样在外部参数实体中适用,下面举例来说明这些问题。【例3.12】元素声明非法使用内部参数实体







]>



Neymar



12345678



aaa@fcbarcelona.com


该文档合法性检验的结果如图318所示。

图318例3.12合法性检验的结果

从错误提示可以知道内部DTD中定义的参数实体不能用于元素的声明。接下来对外部DTD文件Entity.dtd稍作修改如下。






这个时候例3.11的合法性检验结果是失败的,如图319所示。

图319例3.11在Entity.dtd文件修改后合法性检验的结果

从图319中可以很清楚地看到,错误的原因就是在引用参数实体con之前没有对其进行定义。内部参数实体的应用可以使得DTD文档更加简洁,使得DTD文档的可读性以及可维护性更高。3.5.4外部参数实体外部参数实体就是在文档外部定义了,并且只能在DTD中使用的实体。通常这个文档外部的文档也是一个DTD定义语句的文件。这种机制可以将原先很长的DTD文档转化为多个很小并且可以相互调用的DTD文档集合,不同的DTD定义语句可以根据不同的需要、不同的逻辑功能被定义为不同的外部参数实体,然后通过外部参数实体的声明组合成一个DTD。外部参数实体的应用方便了大型DTD文件的开发和设计。外部参数实体既可以在内部DTD中声明也可以在外部DTD中声明,它的定义语法和引用语法如下。定义语法: 

引用语法: 

%实体名;

下面用一个示例来说明外部参数实体的应用。【例3.13】外部参数实体



%con;
]>



Neymar



12345678



aaa@fcbarcelona.com


文件Entity_DTD.txt代码如下。




这个文档是合法的,检验结果如图320所示。

图320例3.13合法性检验的结果

3.6属性的声明属性是由=分割开的成对的属性名和属性值构成的。属性只能出现在元素标记的内部,而且只能出现在元素起始标记的内部,不能出现在结束标记中。属性包含了有关元素内容的信息。例如,下面的示例就是利用属性包含了元素内容年龄和性别信息。


Neymar

属性的定义语法如下: 

是专门用于声明属性的标记。对应的元素名是指拥有该属性的元素名; 属性类型是指属性必须是规定的有效属性类型的一种,这将在3.6.1节详细介绍; 属性默认值实际是指对属性值的要求,这将在3.6.2节详细介绍。以本章一开始提到的Teams.dtd文档为例: 







Age CDATA #REQUIRED
Sex (Male | Female) "Male">

最后的一段语句就定义了元素Member的两个属性: Age和Sex。Age属性的内容为非标记文本,而且Age属性必须包含在元素中; Sex属性的内容从Male和Female中选择,并且规定了Sex属性的默认值为Male。3.6.1设置属性的类型属性的取值必须按照规定的格式进行,在XML中属性的类型可以分为10种,如表33所示。

表33属性的类型及其含义

属性类型含义CDATA可解析的文本数据Enumerated枚举列表中的一个值ENTITY文档中的一个实体ENTITIES文档中的一个实体列表ID文档中唯一的取值IDREF文档中某个元素ID属性值IDREFS文档中若干个元素的ID属性值NMTOKEN合法的XML名称NMTOKENS合法的XML名称的列表NOTATIONDTD中声明的记号名
1. CDATA型数据所谓的CDATA型数据,就是指属性的取值必须是可解析的文本数据,不能包含小于号(<)及引号("),小于号和引号可以通过实体引用的方式插入到属性值中。它是最常用的属性类型,其定义的语法如下。

2. Enumerated型数据Enumerated型数据是指通过|分隔可能的属性值列表,用户可以从列表中选取一个作为属性值,而且属性的默认值必须存在于列表中。其定义的语法如下。

以Teams.dtd中对Sex属性的定义语句为例。

上面这个语句为Member元素定义了一个Sex属性,这个属性的取值必须从Male和Female中选择,而且属性的默认值为Male。对于Enumerated型数据,属性的取值必须从列表中选择,否则将会出现错误。【例3.14】Enumerated型数据







Age CDATA #REQUIRED
Sex (Male | Female) "Male">
]>





FC Barcelona



Spain



Neymar




可以看到例3.14文档中Member元素的属性Sex的取值并没有按照DTD中定义的那样从列表中选择一个,而是换成了其他值,因此该文档不是一个合法的文档,其合法性检验的结果如图321所示。

图321例3.14文档合法性检验的结果

3. ENTITY型数据这一类型的数据用于表示外部不可解析的实体,如二进制文件等。其定义语法如下。

【例3.15】ENTITY型数据







Age CDATA #REQUIRED
Sex (Male | Female) "Male">

]>





FC Barcelona



Spain



&pic;




该文档合法性检验的结果如图322所示。

图322例3.15文档合法性检验的结果

4. ENTITIES型数据这一类型的数据同ENTITY型数据类似,不同点是这一类型的属性可以存储一个实体列表,其定义语法如下。

【例3.16】ENTITIES型数据







Age CDATA #REQUIRED
Sex (Male | Female) "Male"
Pic ENTITIES #REQUIRED
>


]>





FC Barcelona



Spain



Neymar




5. ID型数据ID型数据是指该类型的属性的取值在XML文档中必须是唯一的,不能出现重复,这种类型的数据通常用作元素的标识,其定义语法如下。

【例3.17】非法使用ID型数据







]>





FC Barcelona



Spain



Neymar



Thiago




可以看到,上面文档中Member元素的Number属性的取值出现重复,与定义的ID数据类型相冲突,因此该文档不是一个合法的文档,其合法性检验结果如图323所示。

图323例3.17合法性检验的结果

6. IDREF型数据IDREF型数据与前面提到的ID型数据有着紧密的关系,它是用于表示XML文档中元素之间的一种联系,它的取值必须是XML文档中被定义好的某一元素的ID类型属性值,其定义语句如下。

【例3.18】IDREF型数据






Number ID #REQUIRED
LastNumber IDREF #IMPLIED>
]>





FC Barcelona



Spain



Neymar



Thiago




7. IDREFS型数据IDREFS型数据与IDREF型数据类似,不同点是这种类型的属性的取值可以是文档中已经定义好多个元素的ID型属性值,这些取值之间必须用空格隔开。它可以用于描述一个元素与其他多个元素之间的关系,其定义语法如下。

【例3.19】IDREFS型数据







Number ID #REQUIRED
Friend IDREFS #IMPLIED>
]>





FC Barcelona



Spain



Neymar



Thiago



Messi




8. NMTOKEN型数据NMTOKEN是Name Token的简写,NMTOKEN型数据是指合法的XML名称,它表示由一个或多个字母、数字、句点、连字号或下画线所组成的名称。除了第一个字符位置外,也可以是冒号。它的作用是对属性的取值进行限制,即规定了合法的命名机制,这种属性类型的定义语法如下。

【例3.20】非法使用NMTOKEN型数据








]>





FC Barcelona



Spain



Neymar




可以看到,在NMTOKEN类型属性Nickname的取值中出现了空格,按照规定,这个文档不是合法的文档,其合法性检验的结果如图324所示。

图324例3.20合法性检验的结果

9. NMTOKENS型数据NMTOKENS型数据与NMTOKEN型数据类似,它能够给一个元素的属性赋予多个NMTOKEN类型的数据,不同的NMTOKEN数据之间用空格隔开,其定义语法如下。

【例3.21】NMTOKENS型数据








]>





FC Barcelona



Spain



Neymar




再来看该文档的合法性检验结果,如图325所示。

图325例3.21合法性检验的结果

可以看到,这个时候该文档已经是一个合法的文档了,但是原先的“Young Neymar”字符串已经被解析器认定为两个字符串“Young”和“Neymar”的组合了。10. NOTATION型数据NOTATION型数据用于在XML声明特定的记号。前面刚刚对ENTITY与ENTITIES类型的属性的取值做了介绍,如何展现这些不可解析的实体并进行应用呢?一种办法就是让分析软件进行分析,查看该实体需要什么样的软件进行支持; 另外一种就是通过定义NOTATION属性来指定该属性的支持软件。其定义语法如下。

【例3.22】NOTATION型数据







Pic ENTITY #REQUIRED
Show NOTATION (JPG | GIF) "JPG" >



]>





FC Barcelona



Spain



Neymar




需要注意的是NOTATION类型属性的属性值必须在DTD中通过NOTATION关键字进行定义,不能任意取值。3.6.2属性的默认设置在3.6.1节的属性定义语法中可以知道,除了要定义属性的类型,还需要定义属性的默认值,这个可以称为属性的默认设置。属性的默认设置包含4种方式,除了设定默认值之外,还包括对属性取值的要求,这些要求可以分为3类: #REQUIRED、#IMPLIED、#FIXED。具体的含义如表34所示。

表34属性的默认设置及其含义

元素内容说明含义只有默认值如果元素中不包含该属性,解析器将默认值作为属性值。否则,该属性可以有其他值#REQUIRED元素的每个实例都必须包含该属性#IMPLIED元素的每个实例可以选择是否包含该属性#FIXED元素的属性取值不能更改,只能为设定好的默认值,如果元素的实例中不包含该属性,系统自动将该默认值作为元素的属性值
1. #REQUIRED#REQUIRED关键字表示该属性在元素中不可缺少。【例3.23】非法使用#REQUIRED设置







Age CDATA #REQUIRED
Sex (Male | Female) "Male">
]>





FC Barcelona



Spain



Neymar




属性Age被定义为#REQUIRED,因此在元素Member的实例中必须包含该属性。本例中缺少了Age属性,因此该文档不是一个合法的文档,其合法性检验结果如图326所示。
2. #IMPLIED#IMPLIED表示该属性在包含它的元素中可以出现也可以不出现,如果将上例中的Age属性的默认设置改为#IMPLIED型,它就是一个合法的文档。【例3.24】#IMPLIED设置






Age CDATA #IMPLIED
Sex (Male | Female) "Male">
]>





FC Barcelona



Spain



Neymar




图326例3.23合法性检验的结果

3. #FIXED#FIXED默认设置表示该属性的取值保持不变,而且必须指定该属性的默认取值。如果在包含它的元素的实例中没有出现该属性,元素自动将该默认值作为属性值。【例3.25】#FIXED设置






Age CDATA #IMPLIED
City CDATA #FIXED "Barcelona"
Sex (Male | Female) "Male">
]>





FC Barcelona



Spain



Neymar




Member元素的实例中并没有出现City属性,但是City属性的默认值是“Barcelona”。本 章 小 结 DTD设置了有效的XML文档必须遵循的规则。 DTD可以分为内部DTD和外部DTD两类。 元素的内容可以为#PCDATA、EMPTY、ANY、子元素和混合型内容。 #PCDATA表示元素的内容只能是可解析的文本数据。 EMPTY表示元素内容为空。 ANY表示任意的元素内容。 子元素表示元素的内部只能是子元素。 混合型内容表示元素的内部可以是可解析的文本数据,也可以是子元素,甚至是两者的结合。 如果DTD中的元素名称后面跟有一个星号“*”,那么这个元素可以不出现、出现一次或多次。 如果DTD中的元素名称后面跟有一个加号“ ”,那么这个元素可以出现一次或多次。与星号“*”不同的是,该元素至少要出现一次。 如果DTD中的元素名称后面跟有一个问号“?”,那么这个元素可以不出现或只出现一次。 “|”字符代表“或”,意思是一个或者另外一个命名元素可以出现。有了或字符,就可以选择一个或多个元素。 实体根据其所处的位置不同可以分为内部实体和外部实体。 内部一般实体是指在XML文档内部定义的并且可以在XML文档中使用的实体。 外部一般实体是指实体是在XML文档外部定义,然后通过URL在文档内部进行引用。 内部参数实体是指在DTD中定义的并且只能在DTD中引用的实体。 外部参数实体是指在XML文档外部定义的,并且只能在DTD中引用的实体。 属性只能出现在开始标记和空元素标记中。属性的声明以ATTLIST开头,后面紧跟属性所述的元素名称,然后才是每个属性的定义。 CDATA型数据就是指属性的取值必须是可解析的文本数据。 Enumerated型数据是指通过“|”分隔可能的属性值列表,用户可以从这些列表中选取其中的一个作为属性值,而且属性的默认值必须为列表中的一个。 ENTITY型数据用于表示外部不可解析的实体,如二进制文件等。 ENTITIES型数据与ENTITY型类似,不同的是这一类型的属性可以存储一个实体序列。 ID型数据是指元素的该类型的属性的取值在XML文档中必须是唯一的,不能出现重复,这种类型的数据通常用于作为元素的标识。 IDREF型数据与ID型数据有着紧密的关系,它是用于表示XML文档中元素之间的一种联系,它的取值必须是XML文档中被定义好的某一元素的ID类型属性值。 IDREFS型数据与IDREF型数据类似,不同点是这种类型的属性的取值可以是文档中已经定义好多个元素的ID型属性值,这些取值之间必须用空格隔开。 NMTOKEN型数据是指合法的XML名称,它的作用是对属性的取值进行限制,通俗点讲就是规定了合法的命名机制。 NMTOKENS型数据与NMTOKEN型数据类似,它能够给一个元素的属性赋予多个NMTOKEN类型的数据,不同的NMTOKEN数据之间用空格隔开。 NOTATION型数据用于在XML声明特定的记号。 属性的默认值分为3类: #REQUIRED、#IMPLIED和#FIXED。#REQUIRED表示该属性在元素中不可缺少; #IMPLIED表示该属性在包含它的元素中可以出现,也可以不出现; #FIXED表示该属性的取值保持不变,而且必须指定该属性的默认取值,如果在包含它的元素的实例中没有出现该属性,元素就自动将该默认值作为属性值。思考题1. 什么是DTD?谈谈对DTD的理解。2. DTD的声明方式有哪些?3. 元素的内容可以分为哪几类?4. 属性设置的默认值有哪些?它们的含义各是什么?5. 使用外部DTD的声明,为例2.8创建一个DTD文档。6. 为一个XML文档创建外部DTD。该XML文档的结构要求如下。(1) 根元素名称为Library。(2) Library必须包含两个元素: Book和Member,分别表示书的详细信息和发行人。(3) Book必须包含一个BookId属性。所有其他的元素,如Title、Author、Price、Publisher和Cost都只能作为Book的子元素。(4) 元素Member包含Name和Address两个子元素。元素Name包含FirstName、MiddleName和LastName 3个子元素。元素Address包含HouseNumber、Street、City 3个子元素。

XML技术应用(第二版) pdf下载声明

本pdf资料下载仅供个人学习和研究使用,不能用于商业用途,请在下载后24小时内删除。如果喜欢,请购买正版

pdf下载地址

版权归出版社和作者所有,下载链接已删除。如果喜欢,请购买正版!

链接地址:XML技术应用(第二版)