Professional Documents
Culture Documents
XML 实用教程
主 编 丁跃潮 张 涛
副主编 叶文来 刘韵华
参 编 丁 潇 张天桥 程旭曼
内 容 简 介
可扩展标记语言 XML 是一种新的 Web 开发辅助语言,利用它可以通过 Internet/Intranet 进行信息的描
述、交换和显示。本书是学习和应用 XML 语言的实用教材,书中阐述了 XML 的基本概念、语法规则、
文档类型定义(DTD)、Schema 结构、层叠样式单(CSS)、数据源对象(DSO)、文件转换(XSLT)、文档对象
模型(DOM),还介绍了在 Java、ASP 和.NET 以及电子商务环境下 XML 的应用。为适应没有任何 Web 编
程知识的读者,还介绍了 HTML 基础知识。本书内容由浅入深,全书 13 章分初、中、高级入门 3 个层次,
适合各类读者。在讲解基本概念和基础知识的同时给出了大量实例。每章还包括了教学提示、教学目标、
小结和习题,便于读者巩固所学的知识。
本书适合具有一定计算机基础知识的读者阅读,可作为计算机及相关专业本科 Web 设计或 XML 课程
的教材,也可作为大专院校非计算机专业学习计算机基础的教学参考书和自学用书,还可供从事 Web 应
用软件设计的科研人员参考。
市版权局著作权合同登记号 图字:01-2003-8586 号
图书在版编目(CIP)数据
ISBN 7-301-10462-6
Ⅰ.X… Ⅱ.①丁…②张…Ⅲ. 可扩充语言,XML—程序设计—高等学校—教材 Ⅳ. TP312
中国版本图书馆 CIP 数据核字(2005)第 161303 号
书 名:XML 实用教程
著作责任者:丁跃潮 张 涛 主编
责 任 编 辑:周 欢
标 准 书 号:ISBN 7-301-10462-6/TP·0870
出 版 者:北京大学出版社
地 址:北京市海淀区成府路 205 号 100871
网 址:http://cbs.pku.edu.cn http://www.pup6.com
电 话:邮购部 62752015 发行部 62750672 编辑部 62750667 邮购部 62752015
电 子 信 箱:pup_6@163.com
排 版 者:北京东方人华北大彩印中心 电话:62754190
印 刷 者:
发 行 者:北京大学出版社
经 销 者:新华书店
787 毫米×1092 毫米 16 开本 20.25 印张 486 千字
2006 年 1 月第 1 版 2006 年 1 月第 1 次印刷
定 价:26.00 元
本系列教材编写目的和教学服务
《21 世纪全国应用型本科计算机系列实用规划教材》在全国的各位编写老师的共同辛
勤努力下,在编委会主任刘瑞挺教授和其他编审委员会成员的悉心指导下,经过北京大学
出版社第六事业部各位编辑的刻苦努力,终于与师生们见面了。
教材编写目的
目前,我国高等教育正迎来一个前所未有的发展机遇期。高等教育的发展已进入到一
个新的阶段。高等本科院校也逐渐演变成“研究型、学术型”和“应用型、就业型”两类。
作为知识传承载体的教材,在高等院校的发展过程中起着至关重要的作用。但目前教
材建设却远远滞后于应用型人才培养的步伐,许多院校一直沿用偏重于研究型的教材,应用
型教材比较缺乏,这势必影响应用型人才的培养。
为顺应高等教育普及化迅速发展的趋势,配合高等院校的教学改革和教材建设,坚持
“因材施教”的教学原则,注重理论联系实际,全面促进高等院校教材建设,进一步提高
我国高校教材的质量,北京大学出版社大力推出高校“应用型本科”各专业相关教材。本
系列教材不仅讲解基础理论技术,更突出工程实际应用,注重技术与应用的结合。
本套计算机系列教材的编写思想主要如下:
(1) 要符合学校、学科的计算机课程设置要求。以高等教育的培养目标为依据,注重
教材的科学性、实用性、通用性,尽量满足同类专业院校的需求。
(2) 要定位明确。要准确定位教材在人才培养过程中的地位和作用,正确处理系列教
材与系列课程、读者层次的关系,面向就业,突出应用。
(3) 合理选材和编排。教材内容应处理好传统内容与现代内容的关系,大力补充新知
识、新技术、新工艺、新成果。根据教学内容、学时、教学大纲的要求,制定模块化编写
体例,突出重点、难点。
(4) 体现建设“立体化”精品教材的宗旨。提倡为主干课程配套电子教案、学习指导、
习题解答、课程设计、毕业设计等教学配套用书。
教学服务
1.提供教学资源下载。本系列大部分教材中涉及到的实例(习题)的原始图片和其他
素材或者是源代码、原始数据等文件,都可以在相关网站上下载。每本教材都配有 PPT 电
子教案,老师可随时在网络上下载并可修改为适合自己教学的 PPT。
2.提供多媒体课件和教师培训。针对某些重点课程,我们配套有相应的多媒体课件,
对大批量使用本套教材的学校,我们会免费提供多媒体课件。另外,我们还将免费提供教
师培训名额,不定期组织老师进行培训。
3.欢迎互动。欢迎使用本系列教材的老师和同学提出意见和建议,有建设性的将给予
奖励;同时有教材或者专著出版要求的老师,请与我们联系。
北京大学出版社第六事业部(http://www.pup6.com)
《21 世纪全国应用型本科计算机系列实用规划教材》
专家编审委员会
(按姓氏笔画排名)
主 任 刘瑞挺
崔广才 谢红薇
陈仲民 胡 明 秦 锋 龚声蓉
《21 世纪全国应用型本科计算机系列实用规划教材》
分系列专家编审委员会名单
(按姓氏笔画排名)
计算机应用技术——
主 任 胡昌振
副主任 杨 璐 龚声蓉
委 员 云 敏 马秀峰 李 明 肖淑芬 周松林
杨长生 钟 声 赵忠孝 高 巍
软件开发与软件工程——
主 任 谢红薇
副主任 叶俊民 陈天煌
委 员 王建国 孙 辉 吕海莲 李福亮 何朝阳
张世明 陈佛敏 贺 华 赵绪辉 徐庆生
徐 辉
硬件与网络技术——
主 任 崔广才
副主任 范冰冰 胡 明
委 员 龙冬云 冯嘉礼 曲朝阳 汤 惟 张有谊
董春游 程小辉
专业基础课——
主 任 段禅伦
副主任 陈仲民 秦 锋
委 员 王昆仑 王 虹 仇 汶 田敬军 刘克成
朴春慧 吴晓光 苏守宝 陈付贵 昝风彪
谭水木 魏仕民
21 世纪全国应用型本科计算机系列实用规划教材
联合编写学校名单(按拼音顺序排名)
1 安徽财经大学 23 杭州师范学院
2 安徽工业大学 24 合肥工业大学
3 安阳师范学院 25 合肥学院
4 北华大学 26 河北经贸大学
5 北京化工大学 27 河南科技学院
6 北京建筑工程学院 28 黑龙江八一农垦大学
7 北京理工大学 29 黑龙江科技学院
8 渤海大学 30 湖南大学
9 长春大学 31 湖北经济学院
10 长春工业大学 32 孝感学院
11 长春理工大学 33 湖州师范学院
12 长春税务学院 34 华北科技学院
13 滁州学院 35 华南师范大学
14 楚雄师范学院 36 华中农业大学
15 东北电力大学 37 华中师范大学
16 福建工程学院 38 华北水利水电学院
17 福建师范大学 39 淮北煤炭师范学院
18 广西财经学院 40 黄石理工学院
19 桂林工学院 41 吉林农业大学
20 哈尔滨理工大学 42 集美大学
21 海南大学 43 江汉大学
22 韩山师范学院 44 江苏科技大学
45 内蒙古大学 64 苏州大学
46 南昌工程学院 65 台州学院
47 南京航空航天大学 66 太原理工大学
48 南开大学 67 太原师范学院
49 南阳理工学院 68 唐山师范学院
50 宁波工程学院 69 同济大学
51 平顶山学院 70 皖西学院
52 青岛理工大学 71 武汉大学
53 青岛科技大学 72 武汉科技学院
54 青海民族学院 73 武汉理工大学
55 曲阜师范大学 74 武夷学院
56 山西大学 75 忻州师范学院
57 山西广播电视大学 76 新疆石油学院
58 陕西理工学院 77 许昌学院
59 上海第二工业大学 78 玉溪师范学院
60 上海海事大学 79 浙江工业大学之江学院
61 沈阳大学 80 衢州广播电视大学
62 沈阳化工学院 81 中国农业大学
63 石家庄铁道学院 82 中国石油大学
前 言
·VI·
信息技术的应用化教育
(代丛书序)
刘瑞挺/文
北京大学出版社第六事业部组编了一套《21 世纪全国应用型本科计算机系列实用规划
教材》。为了做好这项工作,他们制订了详细的编写目的、丛书特色、内容要求和风格规范。
在内容上强调面向应用、任务驱动、注重实例分析、培养能力;在风格上力求文字精练、
脉络清晰、图表丰富、版式明快。
一、组编过程
2004 年 10 月,该部开始策划教材丛书,派出编辑分别深入各地高校,了解教学第一
线的情况,物色合适的作者。2005 年 4 月 16 日在北京大学召开了“《21 世纪全国应用型
本科计算机系列实用规划教材》研讨会”。来自全国 73 所院校的 102 位教师汇聚一堂,共
同商讨应用型本科计算机系列教材建设的思路,并对规划选题进行了分工。2005 年 7 月 21
日在青岛又召开了“《21 世纪全国应用型本科计算机系列实用规划教材》审纲会”。编审
委员会成员和 46 个选题的主编、参编,共 100 多位教师参加了会议。审稿会分专业基础课、
软件开发与软件工程、硬件与网络技术、计算机应用技术等小组对大纲及部分稿件进行了
审定,力争使这套规划教材成为切合当前教学需要的高质量的精品教材。
二、转变观念
为了搞好这套教材,要转变一些重要的观念。
首先,需要转变的观念就是大学及其培养人才的定位。大学并不都是“研究型”的,每
个大学生不一定都当科学家。事实上,大多数学校应该是“应用型”的,大学生将直接进
入社会基层、生产一线、服务前沿,成为各行各业的实践者和带头人。
其次,应该转变的观念就是教材建设的思路。许多人偏爱于“研究型”的教材,即使
写“应用型”教材,也多半是对前者进行删繁就简、避虚就实,这样还不能产生真正“应
用型”的教材。因此,以“学科”为中心、追求雄厚“理论基础”的传统应该被以“应用”
为导向、追求熟练“实践技能”的思路所取代。
第三,必须转变对计算机技术的认识。20 年前,有人把计算机技术理解为 BASIC 编
程;10 年前,有人把 Windows 95 和 Word 称为计算机文化;今天,中小学陆续开出《信息
技术》课,有人对此怀疑观望,其实它意义深远。以计算机为核心的信息技术,今后 20 年
的发展主题将是在各个领域的应用普及。大学计算机应用型本科的教材建设应该面向信息
技术的深入应用,而不是相反,因为信息时代已经不是遥远的未来。
三、信息技能
以计算机为核心的信息技术,从一开始就与应用紧密结合。例如,ENIAC 用于弹道计
算,ARPANET 用于资源共享以及核战争时的可靠通信。即使是非常抽象的图灵机模型,也
II
与第二次世界大战时图灵博士破译纳粹密码的工作相关。
今天的信息技术有三个重要的特点:
第一,信息技术是计算机与通信技术融合的辉煌成果。长期以来,计算机技术和通信
技术并行不悖地独立发展。20 世纪后半叶,两者相互渗透,产生了程控电话、数据通信、网
络技术、高清晰电视,世界各国构建了全球的、宽带的、网站密布的信息高速公路,出现
了无处不在的手机通信和移动办公系统、随身听、数码摄录相机、家庭影院、智能控制系
统,还有越来越多的嵌入式系统。人们的工作方式和生活方式都发生了质的飞跃。
第二,信息技术与各行各业紧密结合。我国的职业门类有:农林牧渔、交通运输、生
化与制药、地矿与测绘、材料与能源、土建水利、制造、电气信息、环保与安全、轻纺与
食品、财经、医药卫生、旅游、公共事业、文化教育、艺术设计传媒、公安、法律,这些
门类都需要信息技术。
第三,在发展初期,以计算机为核心的信息技术是一项专门技术,只有专家才需要它、
才能掌握它,在专家与平民之间有很深的“信息鸿沟”。今天,信息技术已经不再是只有专
家才需要、才能掌握的专门技能,而是普通人都需要、也都能掌握的基本信息技能。但是,
“信息鸿沟”也迁移到普通人之间。具有信息优势的学生能良性循环,强者更强。
有了这样广阔的应用信息背景,再造计算机应用型本科的课程体系就有了基础。
四、能力结构
关于应用型计算机人才的能力结构,我们不用“宫殿”模型,而用“雄鹰”模型。前
者是建筑学模型,适合描述学科;后者是生物学模型,适合描述人才。“雄鹰”模型包括主
体、两翼、头部、尾部等,它有可成长性。
首先,数据是信息技术的主体,数据技术是基本功。通常,数据包括文字、公式、表
格、图形、图像、动画、声音、视频等等。因此,你不仅要会录入文章、绘制图表,还应
该会采集音乐、编辑视频。大家面对的是多媒体数据,应该能收集它、整理它,数据经过
整理就成为有用的信息。
其次,信息技术的两翼是数据库技术和网络技术。为了管理好、使用好数据,就必然
用到数据库技术,数据库技术是一切信息管理的基石。为了分享数据和信息,就需要网络
技术。有了上述数据主体技术和两个“翅膀”,你应该可以起飞了。
但是能飞多高,能飞多远,还应该有编程技术、智能技术、安全技术的支持。这相当
于头尾各部分的作用。编程将使大家的信息技能游刃有余。人工智能使你飞得更远,安全
技术能使你飞得更稳。
有人可能会责难我们,难道大学本科生还需要学习办公软件的技能吗?他们认为这是
让人“笑掉大牙”的事。其实,办公软件是最重要的提高生产效率的应用软件,很容易使
用,但各人使用效率的高低则十分悬殊。我们设想,今后大学生在入学前先学会计算机的基
本操作,我们再开一门高级办公技术的课,通过严格的行业及个人行为规范,对学生进行
应用化训练,养成正确的职业习惯。将来工作时能提高效率、改善质量、降低成本。这决
不是贻笑大方的事。
III
五、初步规划
应用型本科教材的规划是一个长期的战略任务,不是短期的战术行为。因此,目前的
规划教材不可能一步到位,还会保留一些传统的基础课。例如,数字电路与逻辑设计、微
机原理及接口技术、单片机原理及应用等。即使是纯硬件专业的学生,如何学这些传统硬
件课都值得商榷,更何况公共基础课。
我们将分门别类逐步建设好应用型本科的重点课程和教材:
(1) 基础类教材:信息技术导论,计算机应用基础,高级办公技术,数据与操作,密
码与安全,实用数据结构,实用离散数学……;
(2) 数据库类教材:数据库原理与应用,信息系统集成,数据采掘与知识发现……;
(3) 网络类教材:计算机网络,因特网技术,网络管理与安全,网站与网页设计……;
(4) 编程类教材:面向对象程序设计,C++程序设计,Java 程序设计……;
(5) 提高类教材:软件工程原理及应用,人工智能原理及应用……。
新教材要体现教育观念的转变,系统地研究普通高校教学改革的需求,优先开发其中
教学急需、改革方案明确、适用范围较广的教材。注重规划教材的科学性、实用性、易学
性,尽量满足同类专业院校的需求。教材内容应处理好传统与现代的关系,补充新知识、新
技术、新工艺、新成果。
我相信北京大学出版社在全国各地高校教师的积极支持下,精心设计,严格把关,一
定能够建设一批符合应用型人才培养目标的、适应计算机应用型人才培养模式的系列精品
教材,而且能建设一体化设计、多种媒体有机结合的立体化教材,为各门课程配套电子教
案、学习指导、习题解答、课程设计等辅导资料。让我们共同努力吧!
刘瑞挺教授 曾任中国计算机学会教育培训委员会副主任、教育部理科计算机科学教学指
导委员会委员、全国计算机等级考试委员会委员。目前担任的社会职务有:全国高等院校
计算机基础教育研究会副会长、全国计算机应用技术证书考试委员会副主任、北京市计算
机教育培训中心副理事长。
目 录
·VIII·
目 录 ·IX·
·IX·
·X· XML 实用教程
·X·
目 录 ·XI·
·XI·
第1章 引 论
教学提示:信息革命和信息技术的发展,改变了人类的生产和生活方式,带来了信息
社会。随着网络技术的发展,网上信息交流已逐渐成为人们交流思想、感情、成果等的主
要渠道,Internet 成为与报纸、广播、电视并驾齐驱且更优越的第四媒体。现有标记语言
HTML 和与其配合的脚本语言都是有限的。可扩展性标记语言 XML 的出现,把网络表达
语言向前推进了一大步,使得标记语言可以由编程人员按需要进行扩展,其扩展能力是无
限的,这就给 Web 编程带来了革命性进展。本章介绍 XML 这一全新的标记语言的引导知
识,包括标记语言的发展,XML 的特点、应用前景、数据结构、开发和应用环境。
教学目标:了解标记语言的发展和现状,掌握 XML 的特点,理解 XML 的应用前景,
掌握 XML 文档的数据结构和基本语法,了解常用的 XML 开发工具,学会使用一种综合性
工具。
1.1 标记语言的发展
的主体部分。
SGML 是很多大型组织,比如电信、飞机、汽车公司、化工企业和军队的文档标准,
它是与平台无关的、结构化的、可扩展的语言,这些特点使 SGML 在很多公司受到欢迎,
并被用来创建、处理和发布大量的文本信息。
·2·
第1章 引论 ·3·
<tr>
<td width="38">3</td>
<td width="96">XML 文档显示</td>
<td width="54">陈杰</td>
<td width="106">2005 年 6 月 13 日</td>
<td>计算机学院教学楼 108 教室</td>
</tr>
<tr>
<td width="38">4</td>
<td width="96">XML 网页制作</td>
<td width="54">叶文来</td>
<td width="106">2005 年 6 月 17 日</td>
<td>信息工程学院教学楼 315 教室</td>
</tr>
<tr>
<td width="38">5</td>
<td width="96">XML 应用实例</td>
<td width="54">陈杰</td>
<td width="106">2005 年 6 月 21 日</td>
<td>信息工程学院教学楼 315 教室</td>
</tr>
</table>
<ul>
<li>信息发布日期:2005 年 5 月 28 日</li>
<li>联系人:张小英、梅玉婷</li>
<li>电子邮件:<a
href="mailto:xyzhang@jmu.edu.cn">xyzhang@jmu.edu.cn</a></li>
<li>网址:<a
href="http://www.jmu.edu.cn/cs">http://www.jmu.edu.cn/cs</a></li>
</ul>
</body>
</html>
·3·
·4· XML 实用教程
结构的描述,从而体现出数据之间的关系。这样所组织的数据对于应用程序和用户都是友
好的、可操作的。应用 XML,人们可以在自己的领域内自由地交换信息。在 1998 年 1 月,
W3C 公布了 XML 1.0 版本,成为 W3C 的标准,这是计算机史上一个重要的里程碑。
后来,W3C 又用 XML 设计出一个与 HTML 4.0 功能等价的语言,称为 XHTML
(eXtensible Hyper Text Markup Language),使之与 HTML 相兼容。
XML 和 HTML 都属于 SGML 的子集,但与 HTML 不同,XML 有 DTD。XML 是一
种元标记语言,即可以像 SGML 那样作为元标记语言来定义其他文档系统,而 HTML 和由
XML 派生的 XHTML 都是实例符号化语言,不能定义其他文档系统。两者的不同点比较如
表 1-1 所示。
GML(1969)
SGML(1985)
HTML(1993)
XML(1998)
XHTML(1999)
XML 各项技术
·4·
第1章 引论 ·5·
·5·
·6· XML 实用教程
</bookinfo>
<resume>本书是学习计算机专业知识的入门教材,体现计算机专业主干课程的经典教学
内容。全书注重在较低计算机知识背景下系统了解和认识计算机科学的全貌,理解基本原理,掌
握关键概念。
</resume>
<recommendation>推广教材</recommendation>
<chapter>
<title>第 1 章 计算机基础知识</title>
<para>计算机是一种能快速而高效地完成信息处理的数字化电子设备。……</para>
</chapter>
<chapter>
<title>第 2 章 计算机硬件基础</title>
<para>硬件就是构成计算机各部件的实体,是计算机中看得见、摸得到的部分。硬
件是计算机工作的前提。……</para>
</chapter>
</book>
</books>
该文件反映了书的基本信息,介绍了两本书。
XML 有许多特点,其优越性是明显的,因而具有广阔的应用前景。
1. 具有良好的格式
XML 文档格式属于良好格式的文件。HTML 文件中的标记,有些是不需要结尾标记的,
如<br>,有些网页缺少若干结尾标记,照样能正确显示。而 XML 的标记一定要拥有结尾
标记,例如:
<name>张三</name>
即,XML 标记一定是成双成对的。如果没有结尾标记,那么在结束的“>”前,需要
有“/”,表示开头和结尾是在同一标记内,例如:
<book sales="yes"/>
2. 具有验证机制
XML 的标记是程序员自己定义的,标记的定义和使用是否符合语法,需要验证。XML
有两种验证方法。一种是 DTD,它是一个专门的文件,用来定义和检验 XML 文档中的标
记。另一种是 XML Schema,用 XML 语法描述。它比 DTD 更优越,多个 Schema 可以复
合使用 XML 名称空间,可以详细定义元素的内容及属性值的数据类型。
·6·
第1章 引论 ·7·
3. 灵活的 Web 应用
在 XML 中数据和显示格式是分开设计的,XML 元数据文件就是纯数据的文件,可以
作为数据源,向 HTML 提供显示的内容,显示样式可以随 HTML 的变化而丰富多彩。也
就是说,HTML 描述数据的外观,而 XML 描述数据本身,是文本化的小型数据库表达语
言。HTML 数据和显示格式混在一起,显示出一种样式。XML 采用的标记是自己定义的,
这样数据文件的可读性就能大大提高,也不再局限于 HTML 文件中的那些标准标记了。由
于 XML 是一个开放的基于文本的格式,它可以和 HTML 一样使用 HTTP 进行传送,不需
要对现存的网络进行改变。
数据一旦建立,XML 就能被发送到其他应用软件、对象或者中间层服务器中做进一步
的处理,或者可以被发送到桌面用浏览器浏览。XML 和 HTML、脚本、公共对象模式一起
为灵活的 3 层 Web 应用软件的开发提供了所需的技术。
4. 丰富的显示样式
XML 数据定义打印、显示排版信息主要有 3 种方法:用 CSS(Cascading Style Sheet)
定义打印和显示排版信息,用 XSLT 转换到 HTML 进行显示和打印,用 XSLT 转换成 XSL
(eXtensible Stylesheet Language)的 FO(Formatter Object) 进行显示和打印。这些方法可以显
示出丰富的样式,呈现漂亮的网页。
5. XML 是电子数据交换(EDI)的格式
XML 是为互联网的数据交换而设计的,它不仅仅是 SGML 定义的用于描述的文档,
而且在电子商务等各个领域使数据交换成为可能,如图 1.2 所示。XML 能够应用于各种领
域的原因,就是它具有到目前为止其他方法所不具备的数据描述特点,控制信息不是采用
应用软件的独有形式,而是采用谁都可以看得懂的标记形式来表现,所以 XML 最适合作
为数据交换的标准,这也是 XML 受人关注的原因。
电子商务 编辑出版
XML XML
XML XML
多媒体 网络 电子政务
XML XML
行业文档 数据仓库
图 1.2 各领域电子数据交换示意图
用 XML 可以对数据关系进行定义,形成特有的标准,因此,各行各业都在建立自己
的行业化标准,以应用于网络上处理电子商务,把后台系统通过 Web 站点表现出来。在特
·7·
·8· XML 实用教程
6. 便捷的数据处理
XML 是以文本形式来描述的一种文件格式。使用标记描述数据,可以具体指出开始元
素(开始标记)和结束元素(结束标记),在开始和结束元素之间是要表现的元素数据,这就是
用元素表现数据的方法。标记可以嵌套,因而可以表现层状或树状的数据集合。XML 作为
数据库,既具有关系型数据库(二维表)的特点,也具有层状数据库(分层树状)的特点,能够
更好地反映现实中的数据结构。XML 还可以很方便地与数据库中的表进行相互转换。XML
是不同数据结构体的文本化描述语言。它可以描述线性表、树、图形等数据结构,也能描
述文件化的外部数据结构,因此是一种通用的数据结构。
XML 使计算机能够很简易地存储和读取资料,并确保数据结构精确。由于 XML 是以
文本形式描述的,所以适合于各种平台环境的数据交换。同样由于使用文本来描述内容,
可以越过不同平台的障碍进行正常的数据交换。当然,文本形式也会因为文字代码的不同
造成不能阅读的问题,但在这一点上,XML 有着非常完美的解决方案,避免了一般语言设
计的缺漏,可支持国际化及地区化的格式。
7. 面向对象的特性
XML 的文件是树状结构的,同时也有属性,这非常符合面向对象的编程,而且也体现
出对象方式的存储,Oracle 数据库就使用了这种面向对象的特性。
XML 是信息的对象化语言。DTD 和 Schema 是界面或类(Interface 或 Class),XML 是
对象实例(Object),XSL 是方法和实现(Method 和 Implement)。XML-Data 解决了 XML 类
的 继 承 问 题 , 而 XML 中的资源(URI) 寻址(URL) 、物理实体等又构成了信息的组件
(Component)。XML 的资源描述框架(RDF)是信息导航、浏览、搜索的用户接口(UI)标准。
8. 开放的标准
XML 基于的标准是为 Web 进行过优化的。Microsoft 公司和其他一些公司以及 W3C
中的工作组正致力于确保 XML 的互用性,以及为开发人员、处理人员和不同系统及浏览
器的使用者提供支持,并进一步发展 XML 的标准。
由于 XML 彻底把标记的概念同显示分开,处理者能够在结构化的数据中嵌套程序化
的描述以表明如何显示数据。这是令人难以相信的强大机制,使得客户计算机同使用者间
的交互作用尽可能地减少了,同时减少了服务器的数据交换量和浏览器的响应时间。另外,
XML 使个人数据只能通过更新布告发生变化,减少了服务器的工作量,大大增强了服务器
的升级性能。
XML 是信息的高层封装与运输的标准。因此 XML 也是不同应用系统之间的数据接口
标准,是所有信息的中间层表示,是中间层应用服务器(AS)的通用数据接口,甚至可以用
于数据库技术的数据迁移过程、数据库报告格式中。
·8·
第1章 引论 ·9·
9. 选择性更新
通过 XML,数据可以在选择的局部小范围内更新。每当一部分数据变化后,不需要重
发整个结构化的数据。变化的元素必须从服务器发送给客户,变化的数据不需要刷新整个
使用者的界面就能够显示出来。以往只要一条数据变化了,整个页面都必须重建,这严重
限制了服务器的升级性能。XML 也允许添加新的数据和更改原有的数据。加入的信息能够
流入存在的页面,不需要浏览器发一个新的页面。
XML 是一套完整的方案,有一系列相关技术,包括文件数据验证、显示输出、文件转
换、文档对象和链接等。这些将在后续章节中一一阐述。
世界上永远也不会出现完美的语言,XML 也是一样,它也存在一些的缺陷。第一,它
是树状存储的,虽然搜索的效率极高,但是插入和修改比较困难。第二,XML 的文本表现
手法、标记的符号化等会导致 XML 数据以二进制表现方法的数据量增加,尤其当数据量
很大时,效率成为很大的问题。第三,XML 文档作为数据提供者使用,没有数据库系统那
样完善的管理功能。第四,由于 XML 是元置标语言,任何个人、公司和组织都可以利用
它定义新的标准,这些标准间的通信就成了巨大的问题。因此,人们在各个领域形成一些
标准化组织以统一这些标准,但是这些努力并不一定能够实现理想的结果。
1. 网络服务领域
·9·
·10· XML 实用教程
2. EDI(电子数据交换)
传统的 EDI(Electronic Data Interchange)标准缺乏灵活性和可扩展性。使用 XML,程序
能够理解在交换数据中所表示的商务数据及概念,根据明确的商务规则来进行数据处理并
给出适当的回音。现有开发的原型已证明,基于 XML 的数据交换是构造电子商务应用的
有效而可行的途径。而且 XML 能够和现有的 EDI 系统相结合,并扩展现有的 EDI 应用。
基于 XML 的数据交换必将改变 EDI 的现状,并给电子商务带来新的机遇和活力。
随着 XML 技术的发展和普及,可以预见到 XML 数据必定成为将来网络上商业数据交
换的首选。XML 数据接口会成为所有商业软件的标准配置,虽然,一般的用户可能感觉不
到它的存在,但是 XML 数据却无所不在。
3. 电子商务领域
电子商务的下一波发展浪潮必将跨越目前发展中的障碍,从而呈现出一系列变化带来
的发展生机。需要做的第一步就是将企业之间日常交流和交换的信息尽可能地电子化、统
一化,来满足不同商业系统之间的数据交换需求。Microsoft 公司的电子商务框架 BizTalk
和 OASIS 组织提出的 ebXML 电子商务框架正在朝这个方向发展,它们将在未来的电子商
务,尤其是 BToB 的电子商务中得到应用,BToB 电子商务将会全部是基于 XML 的应用。
XML 的丰富置标完全可以描述不同类型的单据,例如信用证、保险单、索赔单以及各
种发票等。结构化的 XML 文档发送至 Web 的数据可以被加密,并且很容易附加上数字签
名。因此,XML 有希望推动 EDI(Electronic Data Interchange)技术在电子商务领域的大规模
应用。
4. 数据库领域
关系型数据库行业的三大世家——IBM 公司、Oracle 公司和 Microsoft 公司都分别在它
们的数据库产品中提供了对 XML 的支持。Microsoft 公司用代号为 Yukon 的 SQL Server 来
冲杀企业级市场,作为 Microsoft 公司.NET 战略重要部分的 Yukon 正是基于 XML 技术的。
Oracle 公司也已经推出与 XML 有关的产品 XDB(XML 数据库支持)。而 IBM 公司引以为豪
的是其 DB2 和 XML Extender 的完美结合。XML 文档可以定义数据结构,代替数据字典,
用程序输出建库脚本。应用“元数据模型”技术,对数据源中不同格式的文档数据,按照
预先定义的 XML 模板,以格式说明文档结构统一描述,并提取数据或做进一步处理,最
后转换为 XML 格式输出。XML—数据库—网页或文档中的表格,这三者可以互相转换。
XML 文档从本质来看就是数据库,它是数据的集合,每个文件都含有某种类型的数据。
在许多方面看起来它和其他文件没什么区别,但作为一种“数据库”格式,XML 有一些优
点,例如,它是自描述的(所用的标记描述了数据的结构和类型,尽管缺乏语义),可交换
·10·
第1章 引论 ·11·
的,能够以树状或图形结构描述数据;同样它也有缺点,例如,它显得有些烦琐,由于要
对它进行解析和文本转换,所以数据访问速度较慢。
5. Agent(智能体)
构造一个 Agent 所面临的挑战是如何理解接收到的数据。好的 Agent 能智能地解释这
些数据,然后做出相应的反应。倘若送到 Agent 的是 XML 结构化的数据,Agent 就能很容
易地理解这些数据的含义及与它已有知识的关系。基于 XML 的数据交换对于解决 Agent
的交互性问题有重要的作用,XML 及相关技术必将促进 Agent 技术的发展。
XML 能够更准确地表达信息的真实内容,其严格的语法降低了应用程序的负担,也使
智能工具的开发更为便捷。来自不同应用程序的数据也能够转化到 XML 这个统一的框架
中,进行交互、转化和进一步的加工。
从技术上讲,XML 语言只是一种简单得不能再简单的信息描述语言,但从应用角度上
说,XML 的价值就远不止是一种信息的表达工具。事实上,借助 XML 语言,可以准确地
表示几乎所有类型的数字化信息,可以清晰地解释信息的内涵和信息之间的关联,可以在
最短的时间内准确定位用户需要的信息资源。
6. 软件设计元素的交换
XML 也可以用来描述软件设计中有关的设计元素,如对象模型,甚至能描述最终设计
出来的软件。这些基于 XML 的设计元素可以借助 Web 在开发组内进行交换,在不同的开
发工具之间交换。由 IBM 公司、Unisys 公司及其他合作伙伴提出的 XMI(XML Metadata
Interchange)正是朝该方向努力的结果,XMI 阐明了一个开放式信息交换模型,使得用对象
技术工作的软件开发者能用标准的方式在 Internet 上交换软件设计元素。另外,XML 及相
关技术使得软件的分发及更新在 Web 上更容易实现。Microsoft 公司及合作伙伴提出的
OSD(Open Software Description)正是 XML 的一个应用,它定义了一个标记集用来描述软件
包及其与各种客户平台的依赖关系。
1.3.1 层状结构数据模型
XML 文档的数据结构是树状结构,相当于原来的层次型数据库系统。
层次型数据库系统(Hierarchical Database System,HDBS)是以记录型(Record Type)
为基本的数据结构,在不同记录型之间允许存在联系,层次模型在记录间只能允许单线
联系。
在层次模型中,记录型包含若干个字段,字段描述的是实体的属性。各个记录类型及
其字段必须命名,各个记录类型、同一记录类型中各个字段不能同名。每个记录类型可以
·11·
·12· XML 实用教程
定义一个排序字段,也称为码字段,如果定义该排序字段的值是唯一的,则它能唯一地标
识一个记录值。
在层次模型中,使用结点表示记录,每个结点表示一个记录类型,记录(类型)之间的
联系用结点之间的连线表示,这种联系是父子之间的一对多的联系。其限制条件为
(1) 有且仅有一个结点无双亲,这个结点称为根结点;
(2) 其他结点有且仅有一个双亲结点。
层次模型的结构就像一棵倒栽的树,根结点以外的结点有且仅有一个父结点。这就使
得层次数据库系统只能处理一对多的实体联系。
层次模型在理论上可以包含任意(有限)条记录型和字段,但任何实际的系统都会因为
存储容量或实现复杂而限制层次模型中包含的记录型个数和字段的个数。
在层次模型中,具有相同父结点的子结点称为兄弟结点,没有子结点的结点称为叶
结点。
层次模型中结点都是包含若干字段的记录型,同一结点下不允许有相同的子结点,即
兄弟结点不能相同,这是因为字段不能重复。而在 XML 文档中,有些结点是字段,有些
结点是记录,同一层次中的兄弟可以相同,因为相对于父结点来说,它们代表着记录。图
1.3 所示的是层次模型的一个抽象实例。
A1
B1 B2 Bi Bn
C1 C2 C3 C4 C5 C6 C7 C8
D1 D2 D3 D4 D5 D6
E1 E2 E3
图 1.3 层次模型
·12·
第1章 引论 ·13·
books
Recomen- Recomen-
bookinfo resume chapter bookinfo resume capter
dation dation
·13·
·14· XML 实用教程
2. 处理指令
处理指令是用来给处理 XML 文档的应用程序提供信息的,XML 分析器把这些信息原
封不动地传给应用程序,由应用程序来解释这个指令,遵照它所提供的信息进行处理。处
理指令应该遵循下面的格式:
<?处理指令名 处理指令信息?>
如:
<?xml-stylesheet type="text/xsl" href="book.xsl"?>
3. 根元素
根元素是 XML 文档的主要部分。根元素包含文档的数据以及描述数据结构的信息。
以下是 XML 文档中根元素部分的示例。
<books xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
…
</books>
元素可以包含文本、其他元素、字符引用或字符数据部分。没有内容的元素称为空元
素。空元素的开始标记和结束标记可以合并为一个标记,例如:
<sale/>
·14·
第1章 引论 ·15·
5. 属性
属性是使用与特定元素关联的对应“名称—值”的 XML 构造。其中包含的有关元素内
容的信息并非总是用于显示,而是用于描述元素的某种属性。使用等号分隔属性名称和属
性值,并且包含在元素的开始标记中。属性值包含在单引号或双引号中。以下是与 book 元
素关联的 bookcategory 等 4 个属性的示例。
<books>
<book id="018" bookcategory="计算机" amount="560" remain="200"
discount="8.2">
</book>
</books>
6. CDATA
在标记 CDATA 下,所有的标识、实体引用都被忽略,而被 XML 处理程序一视同仁
地作为字符数据看待。CDATA 的形式如下。
<![CDATA[ 文本内容 ]] >
·15·
·16· XML 实用教程
图 1.5 汉化 XMLwriter 界面
2. XML Spy
XML Spy 是 Icon Information-Systems 公司的产品,显示界面如图 1.6 所示。
XML Spy 在功能上较 XMLwriter 有所提高。它支持 Unicode、多字符集,支持
Well-formed 和 Validated 两种类型的 XML 文档,并可编辑 XML 文档、DTD、Schema 以
及 XSLT。其最大特点是提供了 4 种视窗:XML 结构视窗、增强表格视窗、源代码视窗及
支持 CSS 和 XSL 的预览视窗。结构视窗以树状结构编辑 XML 文档(包括 XML、XSL 文档,
但对 DTD 文档的显示相对较为简单);增强表格视窗以表格的方式显示出文档中某一项元
素的数据库项;源代码视窗可以查看和修改文档源码,并且以不同的颜色标注不同的元素;
预览视窗采用内嵌 IE 6.0 的方式在软件内对 XML 文档进行浏览,支持 CSS 和 XSL。
XML Spy 可支持 DTD、DCD(Document Content Descriptions)、XDR(XML-Data Reduced)、
BizTalk、XSD(XML Schema Definition)的编辑与有效性检查。XML Spy 也提供集成开发环
境 IDE,但仍不支持所见即所得。
·16·
第1章 引论 ·17·
3. Stylus Studio
Stylus Studio 6 XML Professional Edition 是 XML 集成开发环境,具有功能强大的 XML
编辑器、XSLT 调试器及其他 XML 工具,从而显著提高了 XML 的开发效率,最大限度地
释放了开发人员的生产力和创造力。
Stylus Studio 提供了一套完全的 XML 工具和特性集,可用于 XML、XSL/XSLT、Xquery、
SQL/XML、Xpath、Web 设计、Web 服务程序、关联数据库、JSP 编辑、XML-Java 调试互
联以及许多其他的 XML 相关技术。Stylus Studio 是一款功能齐全的综合性开发工具。
4. Visual XML
Visual XML 由 Pierre Morel 开发,能够以树状结构显示 XML、DTD 文档。有的版本
支持多种数据库,如 Oracle、Access、SQL Server、Informix、Sybase、DB2,能够实现与
数据库的集成,并可通过 Wizard 方式进行数据库的浏览、SQL 语句和存储过程的创建和执
行,以图形界面实现 XML 元素与数据库对象的绑定,同时创建 XML 文档和 DTD 文档。
但是,Visual XML 创建新文件时的速度比较慢,元素、属性的添加和移位等操作仍不十
分灵活。
·17·
·18· XML 实用教程
6. Xray
Xray 一种具有实时错误检查的 XML 编辑器。它根据 DTD 或者 XML Schema,允许用
户创建格式良好的 XML 文档或验证文档的有效性,并且支持多文档编辑,是一款免费软
件,支持 Windows 的各种平台。
7. Editplus
Editplus 是一个功能强大的编辑器,支持各种常见语言的彩色语法显示,能够允许用户
自定义工具。Editplus 经过配置后可以作为 C、C++、Java、BASIC、Masm 等 DOS 版本语
言开发工具的 Windows 集成环境,编译和运行这些语言的程序。
·18·
第1章 引论 ·19·
1.5 小 结
1.6 习 题
1. HTML 存在哪些缺陷?
2. 请比较 XML 与 HTML 有哪些异同。
3. 为什么说 XML 是元标记语言?
4. 试述 XML 的特点和优越性。
5. XML 的开发和应用需要怎样的环境?
6. 使用XML Spy 或记事本等文本编辑器编辑如下XML 文档,
并保存文件名为code1_3.xml,
然后在 IE 中浏览。
·19·
·20· XML 实用教程
·20·
第1章 引论 ·21·
<password>22345678</password>
<email>greatman@lycos.com</email>
<registerdate>200505</registerdate>
<address>
<zipcode>215006</zipcode>
<phone>0512-61666666</phone>
<street>XX 省 XX 市人民路 616 号</street>
</address>
</customer>
</customers>
·21·
第 2 章 HTML 基础
2.1 HTML 概述
2.1.1 HTML 概述
<html>
<head>
HTML部分 <title>欢迎进入HTML世界</title>
文档头部 </head>
正文部分 <body>
<p>这会是一种很有趣的体验</p>
</body>
</html>
一个 HTML 文件编写完毕后,其执行效果到底如何,应在浏览器中查看一下。
【例 2.1】 编写如下内容,保存文件名为 code2_1.html。
<html>
<head>
<title>第 2 章 HTML 基础</title>
</head>
<body>
HTML 是 Hyper Text Markup Language 的缩写,意思是“超文本标示语言”。它实
际上是专门用来编写网页的一种编成语言。大多数网页的构成基础就是 HTML 语句。
</body>
</html>
值得注意的是,同一个文件在不同的浏览器中显示的效果可能不同。因此,应尽可能
多用几种浏览器查看。
2.2.1 标记的一般特性
作为一种标识语言,构成它的要素是标记,用标记符号来描述信息。标记有很多种,
·23·
·24· XML 实用教程
每一种有自己的含义和作用。浏览时浏览器会根据标记的意义,自动显示效果。概括地说,
一个 HTML 文件中由两大类元素组成:其一是标记,其二是标记的作用对象(如文字、图
形等)。
标记往往是具有特殊含义的英语词组或字母组合(如 title、html 等),其形式不会变化。
标记通常放在“<>”中,可以不区分大小写,也就是说,大写字母与小写字母的意义一样。
对于大多数标记而言,标记是成对的,一个表示开始,一个表示结束。如例 2.1 中的
<title>与</title>就是一对。标记常常使用的格式如下:
<标记符>内容</标记符>
应该注意的是,表示结束的标记符前面有一个斜杠“/”。
2.2.2 常用标记
尽管 HTML 所使用的标记很多,但以下讲述的是最常用的几种。
1. <html>和</html>
这是 HTML 文件所必需的一对标记。<html>居于文件最前面,在文件的开始处;</html>
居于文件最后面,在文件的结尾处。类似于 C 语言中的“{”和“}”。HTML 文件的其他
内容都镶嵌在这对标记中,如例 2.1 中所示。
2. <head>和</head>
这对标记用来指定网页的头部,指明文件信息。文件信息和文本信息共同构成了一个
HTML 文件,或者说,一个 HTML 文件主要由文件信息和文本信息两部分组成。
使用格式如下:
<head>
文字说明
</head>
一般而言,“文字说明”部分的信息要简明扼要。
此对标记可以与<title>及</title>配合使用,也可单独使用。单独使用时,则作为正文的
头部,显示在全部文本信息之前。
3. <title>和</title>
这对标记用来指定网页的标题。它们要包含在<head>和</head>标记之间。使用格式
如下:
<head>
<title>文字说明</title>
</head>
·24·
第2章 HTML 基础 ·25·
5. <hn>和</hn>
这对标记用来指定网页的子标题。它按字体大小分为 6 级,n 分别用 1,2,3,4,5,
6 来表示,也就是说,可以采用以下 6 种格式。
<h1>子标题内容</h1>
<h2>子标题内容</h2>
<h3>子标题内容</h3>
<h4>子标题内容</h4>
<h5>子标题内容</h5>
<h6>子标题内容</h6>
这里,n 的值越大,浏览器显示的字体越小。子标题会以不同于正文的方式显示,会
以加黑、下画线等形式突出显示。子标题长度不限,可以多行。
【例 2.2】 以不同于正文的方式显示各级子标题,代码如源程序 code2_2.html 所示。
<html>
<head>
<title>网页子标题标题字体大小</title>
</head>
<body>
<h1>h1 级子标题内容</h1>
<h2>h2 级子标题内容</h2>
<h3>h3 级子标题内容</h3>
<h4>h4 级子标题内容</h4>
<h5>h5 级子标题内容</h5>
<h6>h6 级子标题内容</h6>
这是正文
</body>
</html>
图 2.3 子标题的分级
6. <br>
这是单个的标记,其作用是换行显示,相当于 Word 中的段落标识符。如果在 HTML
·25·
·26· XML 实用教程
文件中没有使用<br>,那么显示到窗口的边界,则会自动换行。
7. <hr>
此标记会显示一条水平线。这样可以分隔文件中的不同部分,使内容更清晰。
【例 2.3】 换行显示和显示一条水平线,代码如源程序 code2_3.html 所示。
<html>
<head>
<title>这是网页标题</title>
</head>
<body>
望庐山瀑布<br>
唐.李白
<hr>
日照香炉升紫烟,<br>
遥看瀑布挂前川。<br>
飞流直下三千尺,<br>
疑是银河落九天。<br>
</body>
</html>
图 2.4 水平线的使用
2.3 文 字 修 饰
一个网页大多由以下要素构成:文字、图片、表格、动画及声音。在这些元素中,文
字是十分重要的。下面逐一讲述涉及文字的标记。
2.3.1 字号
可以采用多种方式设置文字的大小。不过设置文字的大小后,其效果会受到 IE 中选项
的影响。如图 2.4 所示是【文字大小】设置为【中】时显示的效果。
当把【文字大小】设置为【最大】时,显示效果如图 2.5 所示。
对比图 2.4 和图 2.5 的文字发现,图 2.5 中的文字比图 2.4 中的大。这就说明了 IE 设置
的影响。因此,文字大小设置标记的作用都是相对的。
·26·
第2章 HTML 基础 ·27·
图 2.5 在 IE 中设置文字大小
下面讲述关于字号的标记。
1. <small>和</small>
把文字以小一些的字号显示(默认的字号为“中”),具体效果参看例 2.4。
2. <big>和</big>
把文字以大一些的字号显示,具体效果参看例 2.4。
3. <font size=n>
本标记也用来设置文字的大小。这里 n 是数字,可以为 1,2,3,4,5,6,7。数字
越大,显示的文字也越大。n 的默认值是 3。
此标记一直有效,直到遇到一个新的 n 值或</font>时为止。
如果给出的 n 值有正负号,则表示在当前字号的基础上增大或缩小字号。如“+1”表
示大 1 号。
4. <basefont size=n>
本标记用来设置文字的默认大小。这里 n 的意思与<font size>标记中的相同。
【例 2.4】 设置文字的默认大小,代码如源程序 code2_4.html 所示。
<html>
<head>
<title>设置文字的默认大小</title>
</head>
<body>
显示效果正常字号
<small>小号字</small>
<big>大号字</big><br>
<font size=1>1 号字<br>
<font size=2>2 号字<br>
<font size=3>3 号字<br>
<font size=4>4 号字<br>
·27·
·28· XML 实用教程
图 2.6 设置文字大小的效果
2.3.2 字体样式
除了可以设置文字的大小之外,还可以设置字体的样式(包括颜色)。
1. <b>和</b>
这一对标记配合使用,使放在它们中间的文字以粗体显示,使用格式如下:
<b>要粗体显示的文字</b>
通常用粗体表示强调,它是一种突出显示的效果。
如果只有<b>标记而忘记了</b>标记,则从<b>开始一直都是粗体。
2. <i>和</i>
这一对标记配合使用,使放在它们中间的文字以斜体显示,使用格式如下:
<I>要斜体显示的文字</I>
注意事项与<b>相同。
3. <u>和</u>
这一对标记配合使用,使放在它们中间的文字以下划线显示,使用格式如下:
<u>要下划线显示的文字</u>
·28·
第2章 HTML 基础 ·29·
注意事项与<b>相同。
4. <strike>和</strike>
这一对标记配合使用,使放在它们中间的文字以加上删除线显示,使用格式如下:
<strike>要加上删除线显示的文字</strike>
注意事项与<b>相同。
5. <sub>和</sub>
这一对标记配合使用,使放在它们中间的文字以下标形式显示,使用格式如下:
<sub>要以下标形式显示的文字</sub>
注意事项与<b>相同,下标会比正常字号小。
6. <sup>和</sup>
这一对标记配合使用,使放在它们中间的文字以上标形式显示,使用格式如下:
<sup>要以上标形式显示的文字</sup>
注意事项与<b>相同,上标会比正常字号小。
2.3.3 特殊标记
因为“<”和“>”作为标记的边界符使用了,所以要显示这两个符号,必须转义。具
体情况如下:“<”用“<”,“>”用“>”,“&”用“&”,“"”用“"”。
【例 2.5】 使用字体样式和特殊标记,代码如源程序 code2_5.html 所示。
<html>
<head>
<title>使用字体样式和特殊标记</title>
</head>
<body>
<b>要粗体显示的文字</b>
<i>要斜体显示的文字</i>
<u>要下划线显示的文字</u>
<strike>要加上删除线显示的文字</strike><br>
正常文字<sub>下标形式显示的文字</sub><br>
正常文字<sup>上标形式显示的文字</sup><br>
小于号<<br>
大于号><br>
</body>
</html>
·29·
·30· XML 实用教程
图 2.7 使用字体样式和特殊标记的效果
2.4 列 表
列表是一种条理化地排列信息的方法。它把内容一条条地水平排列显示,直观、清晰。
而它也不同于表格,一般列表没有表格复杂。列表标记使用的通用格式:
<标记>
<条目标记 1>条目内容 1
<条目标记 2>条目内容 2
<条目标记 3>条目内容 3
……
</标记>
值得注意的是,在“条目内容”后不用加换行标记<br>。
1. <dir>和</dir>
把其间包含的内容以列表方式显示,并在每个条目前加上一个标记符号。
2. <menu>和</menu>
与<dir>作用相同,这两个标记比较简单,不能实现复杂的变化。
3. <ul>和</ul>
其效果与上述两个命令的列表效果相似。不过,此命令可以带属性,变成<ul type=f>
的形式。此处 f 为单词,具体情况有如下几种。
f 为 disk:条目以符号“●”引导。
f 为 circle:条目以符号“○”引导。
f 为 square:条目以符号“■”引导。
4. <ol>与</ol>
使用此对标记,也可实现与以上命令相似的列表。不同之处在于,本标记会自动给条
目排序并加上序号。
此标记也可带有属性,有如下两种。
1) < ol type=f>
此处,f 是一个字符,不同的字符表示不同的编号方式,主要有以下几种情况。
·30·
第2章 HTML 基础 ·31·
f 为 A:以大写字母排序。如 A,B,C,D 等。
f 为 a:以小写字母排序。如 a,b,c,d 等。
f 为 I:以大写罗马数字排序。如 I,II,III,IV 等。
f 为 i:以小写罗马数字排序。如 i,ii,iii,iv 等。
f 为 1:以阿拉伯数字排序。如 1,2,3,4 等。
2) <ol start=n>
n 是一个数字,此标记符表示重新定义的起始号。这样一来,可以指定序号的起始号。
【例 2.6】 列表序号的使用,代码如源程序 code2_6.html 所示。
<html>
<head><title>列表序号</title></head>
<body>
<dir>
<LI>李白
<LI>杜甫
<LI>杜牧
</dir>
<menu>
<li>李白----赠孟浩然
<li>杜甫----望岳
<li>杜牧----泊秦淮
</menu>
<ol type=A>
<li>李白----赠孟浩然
<li>杜甫----望岳
<li>杜牧----泊秦淮
</ol>
<ol type=i>
<li>李白----赠孟浩然
<li>杜甫----望岳
<li>杜牧----泊秦淮
</ol>
</body>
</html>
图 2.8 列表序号的效果
·31·
·32· XML 实用教程
5. 列表的嵌套
列表也可以层嵌套,嵌套后的效果参见例 2.7。
【例 2.7】 列表嵌套的使用,代码如源程序 code2_7.html 所示。
<html>
<head>
<title>列表嵌套</title>
</head>
<body>
<h3>唐诗选读</h3>
<ol>
<li>李白
<ul>
<li>春思
<li>月下独酌
<li>赠孟浩然
</ul>
<li>杜甫
<ul>
<li>望岳
<li>佳人
<li>梦李白
</ul>
<li>杜牧
<UL>
<LI>赤壁
<LI>泊秦淮
<LI>秋夕
</UL>
</OL>
</body>
</html>
图 2.9 列表嵌套的效果
·32·
第2章 HTML 基础 ·33·
2.5 表 格
HTML 对页面元素的排版基本就是按照元素在文档中出现的先后顺序,从头至尾依次
排下来的,唯一能控制页面元素位置的只有 align 属性,而它所能控制的情况只有 3 种:左、
中、右。要编制复杂的页面布局仅仅依靠基本的 HTML 几乎是不可能实现的。
表格就解决了这个问题,使用表格基本能实现对页面元素在浏览器中随心所欲的排版
定位。表格通常用来显示大量的、分类化的信息,具有表示清晰、明了的特点,使用十分
广泛。
表格一般由以下几部分组成:表格名称、表格栏及表中数据。这与其他软件(如 Word)
中所说的表格十分相同。
以下讲述建立、修改表格所涉及的标记。
2.5.1 <table>和</table>
这是一对用来指明表格范围的标记。通常使用的格式:
<table>
表格全部内容
</table>
1. border 属性
使用表格的这一属性可以给表格加上框线。如<table border>表示表格是有表格线的,
border 的线宽默认为 1。没有写 border 则表示表格是没有表格线的。
一般用<table border=n>来设置有线表格和边框宽度。n 是一个具体的数字,用来指定宽
度的大小,单位是像素,默认为没有边框。当 n 为 0 时,也没有边框,具体效果参见例 2.8。
【例 2.8】 设置表格和表格边框,代码如源程序 code2_8.html 所示。
<html>
<head>
<title>这是表格和表格边框的例子</title>
</head>
<body>
<table border="2">
<caption>表格标题</caption>
<tr>
<th>栏目名称 1</th>
<th>栏目名称 2</th>
<th>栏目名称 3</th>
</tr>
<tr>
<td>数据 1-1</td>
<td>数据 2-1</td>
<td>数据 3-1</td>
</tr>
·33·
·34· XML 实用教程
<tr>
<td>数据 1-2</td>
<td>数据 2-2</td>
<td>数据 3-2</td>
</tr>
</table>
</body>
</html>
图 2.10 表格和表格边框实例
2. width 属性
这一属性可以用来设置有线表格占整个页面的相对宽度,用法为<table width=n>。n 是
一个具体的数字,可以是一个百分数(如 100%),也可以是一个具体的数值,单位是像素(如
80,表示表格占 80 个像素单位的宽度)。
3. height 属性
这一属性可以用来设置有线表格占整个页面的相对高度。其用法与<table width=n>
相似。
使用相对方式来设置表格大小时,浏览器窗口大小的变化会影响到表格大小的变化。
表格宽度、高度设置要合理,在视觉上要有美感。
【例 2.9】 使用相对方式来设置表格大小,代码如源程序 code2_9.html 所示。
<html>
<head>
<title>这是表格占页面相对大小的例子</title>
</head>
<body>
<table border="5" width=80%, height=50%>
<caption>表格占页面的 80%</caption>
<tr>
<th>栏目名称 1</th>
<th>栏目名称 2</th>
<th>栏目名称 3</th>
</tr>
<tr>
<td>数据 1-1</td>
<td>数据 2-1</td>
·34·
第2章 HTML 基础 ·35·
<td>数据 3-1</td>
</tr>
<tr>
<td>数据 1-2</td>
<td>数据 2-2</td>
<td>数据 3-2</td>
</tr>
</table>
<table border="5" width=70%, height=40%>
<caption>表格占页面的 70%</caption>
<tr>
<th>栏目名称 1</th>
<th>栏目名称 2</th>
<th>栏目名称 3</th>
</tr>
<tr>
<td>数据 1-1</td>
<td>数据 2-1</td>
<td>数据 3-1</td>
</tr>
<tr>
<td>数据 1-2</td>
<td>数据 2-2</td>
<td>数据 3-2</td>
</tr>
</table>
</body>
</html>
图 2.11 设置表格在页面中的相对大小
4. cellspacing 属性
这一属性可以用来设置有线表格的单元格线的宽度,用法为<table cellspacing=n>。n
是一个具体的数值,单位是像素。
·35·
·36· XML 实用教程
5. cellpddeing 属性
这一属性可以用来设置单元格线与数据之间的距离,用法为<table cellpddeing=n>。n
是一个具体的数值,单位是像素,默认值为 1。
2.5.2 <caption>和</caption>
这是一对用来指明表格标题的标记。通常使用的格式:
<caption>
表格标题内容
</caption>
默认的情况下,标题以居中的形式显示,而且显示在表格的上面。标题也可以显示在
表格的下面,这要使用 align 属性,使用格式如下:
<caption align=f>
此处,f 为以下两个单词:top,标题显示在表格之上;bottom,标题显示在表格之下。
2.5.3 <tr>和</tr>
这对标记用来指明表格一行的内容。这一行可以是表格的栏目,也可以是数据。
2.5.4 <th>和</th>
这对标记用来指明表格栏目行中的一项。一行可以由多项组成,必须嵌套在<tr>与</tr>
之中使用。由此标记指定的栏目,文字会突出显示。
2.5.5 <td>和</td>
这对标记用来指明表格数据行中的一项。一行可以由多项组成,它也必须嵌套在<tr>
与</tr>之中使用。由此标记指定的栏目,文字不会突出显示。
本标记的用法参见例 2.8 和例 2.9。
1. align 属性
以上<tr>、<th>及<td>也可以带 align 属性。
align=left:表示居左,如<th align=left>。
align=center:表示居中,如<th align=center>。
align=right:表示居右,如<th align=right>。
特别值得注意的是,这种调整可以针对每一表格单元,因此可以十分灵活地使用。
2. nowrap 属性
在执行<th>及<td>时,当数据较多,一行显示不下时,浏览器会自动换行显示。如果
不要自动换行,可以使用 nowrap 属性。
3. width 属性
在执行<th>及<td>时,使用此属性可以指定宽度。具体用法与在<table>中一样。
·36·
第2章 HTML 基础 ·37·
4. valign 属性
在执行<th>及<td>时,使用此属性可以指定文字显示在本行的上、中、下位置,使用
格式如下:
<valign=f>
此处,f 为以下单词:top,文字显示在本行偏上位置;middle,文字显示在本行中间位
置;bottom,文字显示在本行偏下位置。
5. colspan 属性
在执行<th>及<td>时,使用此属性可以实现单元格的横向合并,使用格式如下:
<colspan=n>
·37·
·38· XML 实用教程
图 2.12 表格栏目合并的效果
2.6 色 彩
2.6.1 色彩的表示
在计算机显示器中,使用红(red)、绿(green)、蓝(blue)3 种颜色来构成各种各样的颜色。
颜色的种类有 16,256 及 65,536 等多种。把这 3 种颜色从 0 到 255 分别编号,再表示为
十六进制数,则红色(rr)就从 00 到 ff,绿色(gg)和蓝色(bb)两种颜色也如此。3 种颜色的表
示合起来就是 rrggbb。这样一来,可以用一种颜色中所含红、绿、蓝成分的程度,数值化
地表示颜色。如黑色为 000000、白色为 ffffff、墨绿色为 008040、深灰色为 808080 等。在
HTML 中,可用这种方式指定颜色。
但是,这种方式指定的颜色多达 256×256×256 种。并非所有的显示器都可显示这么多
种的颜色。当指定了显示器不能显示的颜色时,显示器会以自己可以显示的、最接近的颜
色显示。但这个“最接近的颜色”,也可能偏离设计者原来所想的颜色,这就出现了“变
色”。要解决这一问题,其一可以在其他颜色模式下调试(如把当前颜色改为 16 色,浏览
一下,若不满意可以改);其二也可只使用最常见的 256 种颜色(甚至只 16 色),这是一种保
守的方法。
如果不想使用这种用数值指定颜色的方法,也可以用英文的颜色名称来指定。常见的
颜色见表 2-1。
表 2-1 常见颜色列表
颜 色 名 称 颜 色 名 称
black 黑 red 红
white 白 fuchsia 紫红
navy 深蓝 maroon 棕
blue 蓝 purple 紫
aqua 浅绿 green 绿
teal 靛 olive 橄榄色
silver 银灰(浅灰) lime 柠檬绿
gray 灰 yellow 黄
·38·
第2章 HTML 基础 ·39·
2.6.2 文本的色彩
在 body 的属性中,可以使用以下几种属性改变文本的颜色。
1. text 属性
该属性用来设置文本的颜色。这里所说的“文本”可以是标题、正文及表中的文字,
但不能用于超链接的文字。使用格式为
<text=#rrggbb>
rrggbb 的意义与<text>中的相同。
3. vlink 属性
该属性用来设置鼠标指向的超链接文字时,链接文字的颜色,默认为红色,使用格式为
<vlink=#rrggbb>
rrggbb 的意义与<text>中的相同。
通常情况下,不使用<text>、<link>及<vlink>进行设置,一般都使用默认设置。
4. <font>标记的 color 属性
以上几种属性所指定的都是整个网页中某一类文字的色彩,使用<font>标记的 color 属
性可指定任意一段文字的色彩。这里所说的一段文字,可以为几行、一行甚至只有一个字。
使用格式为
<font color=#rrggbb>
2.6.3 表格的颜色
1. <table>标记的 bgcolor 属性
用来指定整个表格的背景颜色,使用格式为
<table bgcolor=#rrggbb>
2. <td>标记的 bgcolor 属性
用来指定表格中一行的背景颜色,使用格式为
<td bgcolor=#rrggbb>
3. <th>标记的 bgcolor 属性
用来指定表格中栏目行的背景颜色,使用格式为
<th bgcolor=#rrggbb>
·39·
·40· XML 实用教程
用来指定分隔线的颜色,使用格式为
<hr color=#rrggbb>
【例 2.11】 颜色的设置,代码如源程序 code2_11.html 所示。
<html>
<head>
<title>这是颜色设置的例子</title>
</head>
<body>
颜色显示效果<br>
<font color=red>
<hl>问题与答案(红色)<hl>
<hr color=#808080>
<font color=blue>
如何改变表格的背景颜色?(蓝色)<br>
<font color=olive>
这还不简单(橄榄色)。
</body>
</html>
图 2.13 颜色的设置
2.7 超文本链接
超文本链接是网页中一种非常重要的功能,是网页中最重要、最根本的元素之一。通
过链接可以从一个网页转到另一个网页,也可以从一个网站转到另一个网站,这符合人类
的跳跃思维方式。链接的标志有文字和图片两种。可以制作一些精美的图片作为链接按钮,
使它和整个网页融为一体。
2.7.1 超文本链接的概念
所谓的超文本链接是指从一个网页指向一个目标的连接关系,这个目标可以是另一个
网页,也可以是相同网页上的不同位置,还可以是一个图片、一个电子邮件地址、一个文
件,甚至是一个应用程序。而在一个网页中用来超文本链接的对象,可以是一段文本或者
·40·
第2章 HTML 基础 ·41·
是一个图片。当浏览者单击已经链接的文字或图片后,链接目标将显示在浏览器上,并且
根据目标的类型来打开或运行。按照链接路径的不同,网页中的超文本链接一般分为以下
3 种类型:内部链接、锚点链接和外部链接。如果按照使用对象的不同,网页中的链接又
可以分为:文本超链接、图像超链接、E-mail 链接、锚点链接、多媒体文件链接、空链接等。
2.7.2 页面链接
用 HTML 创建超文本链接需要使用<a>标记符(结束标记符</a>不能省略),它的最基本
属性是 href,用于指定超文本链接的目标。通过为 href 指定不同的值,可以创建出不同类
型的超文本链接。
在 HTML 文件中用链接指针指向一个目标,使用格式为
<a href = "…">标记超文本链接信息</a>
其中,标记超文本链接信息可以是文字或图片并显示在网页中,当用户单击它时,浏
览器就会显示由 href 属性中的统一资源定位器(URL)所指向的目标,实际上这个标记超文
本链接信息在 HTML 文件中充当指针的角色,它一般显示为蓝色。href 中的 h 表示超文本,
而 ref 表示“访问”或“引用”的意思。在<a>和</a>之间可以用任何可单击的对象作为超
文本链接的源,例如文字或图像。
例如:
<a href ="http://www.hunu.edu.cn/">湖南大学</a>
用户单击“湖南大学”,即可看到湖南大学的主页内容。在这个例子中,充当指针的
是“湖南大学”。
2.7.3 本地链接
超文本链接可以指向本地计算机中的某一个文件,这种链接方式叫做本地链接。在文
件中需要创建一个标签(即做一个记号),为页面中需要跳转到的位置命名。命名时应使用
<a>标记符的 name 属性。使用格式如下:
<a name=标签名>此处创建了一个标签</a>
·41·
·42· XML 实用教程
图 2.14 使用本地链接
这样设置之后,当用户在浏览器中单击文字“互联网”时,将把“互联网”文字开头
的部分显示在页面的开头。其执行结果如图 2.15 所示。
图 2.15 执行结果
2.7.4 电子邮件链接
若希望用户在网页上通过链接直接打开客户端发送邮件的工具发送电子邮件,则可以
在网页内包含发送电子邮件的功能。实现此功能所需的全部工作就是在链接标记中插入
mailto 值,如:
·42·
第2章 HTML 基础 ·43·
<a href="mailto:webmaster@hnu.cn">管理员信箱</a>
这就创建了一个自动发送电子邮件的链接,“mailto:”后边紧跟想要自动发送的电子
邮件的地址(即 E-mail 地址),当浏览网页的用户单击了指向电子邮件的超文本链接后,系
统将自动启动邮件客户程序(对于安装了 Windows 98/2000 操作系统的计算机,默认时启动
Outlook Express),并将指定的邮件地址填写到【收件人】栏中,用户可以编辑并发送邮件。
2.8 小 结
HTML 是构成网页的最基本的元素,虽然随着技术的发展,又有各种新技术产生,如
PHP、ASP、ASP.NET、JSP 和 J2EE,它们依然是建构在 HTML 之上的,并没有舍弃现有
的 HTML,因为我们还是必须学习 HTML 语法。
HTML 文件是普通的文本文件,再加上一些标记,用以告知 WWW 浏览器有关字形的
变化、表格设置或是一些超文本链接。当用户浏览 WWW 上的信息时,浏览器会自动解释
这些标记的含义,并按照一定的格式在屏幕上显示这些被标记的文件。HTML 的优点是跨
平台性,即任何可以运行浏览器的计算机都能阅读并显示 HTML 文件,不管其操作系统是
什么,并且显示结果相同,呈现出生动、活泼的 WWW 世界。
2.9 习 题
1. HTML 是什么意思?它是一种什么样的语言?
2. HTML 最常用的标记有哪些?
3. 网页主要由哪些要素组成?
4. 用于文字修饰的标记主要有哪些?
5. 用于表格的主要标记有哪些?用表格设计班级通讯录网页。
6. 制作一个网页,网页用表格划分成几个区域。
7. 在<body>的属性中,可以使用哪些属性改变文本的颜色?
8. 用来指定分隔线颜色的具体格式是什么?
9. 制作一个自己的个人主页,网页中有文字链接,并将自己的电子邮箱制作成链接。
·43·
第 3 章 XML 基础
3.1.1 标记的命名规则
作为元标记语言,XML 可以在文档中创建、使用新的标记和文法结构。正是这种优点
使得用户能够根据自己的特殊需要制定出适用于自身的一套标记和文法结构,以便于结构
化地描述自己领域的信息,从而提供一种处理数据的最佳方式。
XML 的可扩展性为开发者进行程序开发提供了自由广阔的空间,但并非所有名字都可
以作为标记名。作为标记名字的字符串必须满足以下要求。
(1) 名称的开头必须是字母或“_”;
(2) 标记名称中不能有空格;
(3) 名称的字符串只能包含英文字母、数字、“_”、“-”、“.”等字符。
例如下面的标记就是合法标记:
<Name>、<name>、<_name>、<lisongtao_name>、<li.name>。
而下面是非法的标记:
<.name>、<li%name>、<li*name>、<li/name>
以上标记的命名规则同时也是后面要讲到的属性的命名规则,以及 XML 文档中其他
实体的命名规则。
3.1.2 标记的使用规则
1. 必须具有根标记且根标记必须唯一
结构良好的 XML 应用程序的根标记必须要唯一。
【例 3.1】 根标记不唯一的 XML 文档,代码如源程序 code3_1.xml 所示。
第3章 XML 基础 ·45·
该程序出错的地方是根标记不唯一。只要在两个标记的外面统一套一个标记<book>
</book>,程序就成为运行正常的 XML 文档了。
2. 开始标记和结束标记需配对使用
在 HTML 中,只有开始标记而没有结束标记的程序往往还能得到正确的显示结果,但
在 XML 文档中这种情况是不允许存在的。
【例 3.2】 开始标记和结束标记不配对的 XML 文档,代码如源程序 code3_2.xml 所示。
<?xml version="1.0" encoding="gb2312" ?>
<bookinfo>
<title>计算机导论</title>
·45·
·46· XML 实用教程
<author>丁跃潮等</author>
<publish>
<publisher>高等教育出版社</publisher>
<ISBN>7-04-014768-8</ISBN>
<pubdate>2004.6</pubdate>
</publisher>
<price>19.7</price>
</bookinfo>
该程序的问题就在于<publish>标记和</publisher>标记不是一对开始和结束标记,这里
只要将<publish>改为<publisher>或将</publisher>改为</publish>问题就解决了。
3. 标记不能交错使用
所谓标记的交错使用就是指如下情形的标记使用。
<publisher><ISBN>7-04-014768-8</publisher></ISBN>
4. 空标记的使用
所谓空标记指的是标记只有开始没有结束,又叫孤立标记。这种标记有的表示一种格
式信息,例如<hr>在 HTML 中代表了一条水平线,有的则保存一些数据信息。空标记可写
成“<标记名/>”的形式。具体使用如例 3.3。
【例 3.3】 空标记的使用,代码如源程序 code3_3.xml 所示。
<?xml version="1.0" encoding="gb2312" ?>
<!-- 这个文档包含网上书店中关于书的描述,文件名 code3_3.xml -->
<!DOCTYPE bookinfo SYSTEM "code3_1.dtd">
<bookinfo>
·46·
第3章 XML 基础 ·47·
<title>计算机导论</title>
<author>丁跃潮等</author>
<publish>
<publisher>高等教育出版社</publisher>
<ISBN>7-04-014768-8</ISBN>
<pubdate>2004.6</pubdate>
</publish>
<bk/>
<price>19.7</price>
</bookinfo>
5. 标记对大小写敏感
HTML 中并不存在大小写敏感问题,但在 XML 中相配对的标记大小写必须相同。
【例 3.4】 标记大小写不匹配的 XML 文档,代码如源程序 code3_4.xml 所示。
<?xml version="1.0" encoding="gb2312" ?>
<bookinfo>
<title>计算机导论</title>
<author>丁跃潮等</author>
<publish>
<publisher>高等教育出版社</publisher>
<ISBN>7-04-014768-8</ISBN>
<pubdate>2004.6</pubdate>
</publish>
<price>19.7</price>
</BOOKINFO>
上面程序中</bookinfo>标记和</BOOKINFO>标记被认为是两个不同的标记,因此<bookinfo>
</BOOKINFO>被认为是两个不配对的标记。程序将显示错误信息,如图 3.3 所示。
·47·
·48· XML 实用教程
3.2.1 处理指令
其中,“<?”和“?>”是开始和结束的界定符号,xml 是处理指令的命令名字;version
是命令中的属性,通常描述处理指令一个特定的细节;1.0 是属性的值,代表了对属性进行
的某一方面的设定。总而言之以上指令就是告诉 XML 解析器,该文档遵守 XML 1.0 规范,
应按照 XML 1.0 的要求来检查。一个结构良好的 XML 文档必须要包含有关版本的声明,
而且有关版本声明的信息必须放在整个 XML 文档的第一行。
【例 3.5】 没有版本声明的 XML 文档,代码如源程序 code3_5.xml 所示。
<?xml encoding="gb2312" ?>
<bookinfo>
<title>计算机导论</title>
<author>丁跃潮等</author>
<publish>
<publisher>高等教育出版社</publisher>
<ISBN>7-04-014768-8</ISBN>
<pubdate>2004.6</pubdate>
</publish>
<price>19.7</price>
</bookinfo>
·48·
第3章 XML 基础 ·49·
该程序的错误在于有关版本声明的信息没有放在第一行,只要将其放在第一行,程序
就是一个结构良好的程序了。之所以要这样做的要求是因为 IE 开始显示一个扩展名为.xml
的文件时,就要立即检测它的版本信息,随后才能进行进一步的程序处理。
·49·
·50· XML 实用教程
还有其他方面的处理指令,在后面章节会进一步说明。
XML 允许为元素设置属性,用来为元素附加一些额外信息,这些信息与元素本身的信
息内容有所不同。一个 XML 可以包含多个属性,从而存储一个或多个关于该元素的数据。
对于非空元素,属性的基本使用格式如下:
<开始标记属性名称 1=“属性值”属性名称 2=“属性值”…></结束标记>
或
<开始标记属性名称 1=“属性值”属性名称 2=“属性值”…></结束标记>
对于空元素,属性的基本使用格式如下:
<空标记属性名称 1=“属性值”属性名称 2=“属性值”…/>
或
<空标记属性名称 1=“属性值”属性名称 2=“属性值”…/>
图 3.6 属性使用效果图
在 XML 中设置属性时应注意:
(1) 要符合 XML 的语法格式,属性值要用引号(单引号或双引号)括起来。如下属性设
置是不合法的。
<book id=001 bookcategory=文艺 amount=100 remain=80 discount=8.7>
·50·
第3章 XML 基础 ·51·
(2) 当属性值本身含有单引号时,则用双引号作为属性的定界符,当属性值本身含有
双引号,则用单引号作为属性的定界符,当属性中既包含单引号,又包含双引号的时候,
属性值中的引号必须用实体引用方式来表示。
(3) 一个元素不可以拥有相同名称的两个属性,不同的元素可以拥有两个相同名称的
属性。如下属性设置中拥有两个名称为 anount 的属性,因此是不合法的。
<book id="001" bookcategory="文艺" amount="100" amount="80"
discount="8.7">
3.2.3 特殊字符的使用
例如要在文档中显示字符“<”和“>”时,必须使用“<”和“>”代替。例 3.8 中
在“文艺”二字的左右边分别加上“<”和“>”符号。
【例 3.8】 特殊字符的使用,代码如源程序 code3_8.xml 所示。
<?xml version="1.0" encoding="gb2312" ?>
<book bookcategory="<文艺> ">
<bookinfo>
<title>计算机导论</title>
<author>丁跃潮等</author>
<publish>
<publisher>高等教育出版社</publisher>
<ISBN>7-04-014768-8</ISBN>
<pubdate>2004.6</pubdate>
</publish>
·51·
·52· XML 实用教程
<price>19.7</price>
</bookinfo >
</book>
图 3.7 特殊字符的使用效果
任何成熟的计算机程序语言都必须有注释语句,对文档中其他形式的语句进行提示或
说明。这是进行大型程序设计至关重要的一项要求,XML 文档也不例外。XML 文档中的
注释和 HTML 文档中的注释是一样的,都是以下列开始符号和结束符号界定的一行或多
行代码。
<!--
…
-->
HTML 标记语言中有一个<pre>标记,叫做预定义格式标记,该标记当中的内容将按原
有格式被显示出来。和 HTML 中的<pre></pre>标记有点相似,XML 标记语言中也有一个
对应的标记,即 CDATA 标记。但这里注意,它们只是相似,本质上还有很大的不同。CDATA
标记的作用是通知 XML 语法解析器,该标记中的代码包括文字和标记都要当成纯文本来解
析,并原封不动的将这段代码传给下一个 XML 应用程序。界定该段代码的开始和结束标记为
<![CDATA[
… ]]>
·52·
第3章 XML 基础 ·53·
·53·
·54· XML 实用教程
3.3.1 CSS
3.3.2 DTD
3.3.4 XSL
·54·
第3章 XML 基础 ·55·
XML 是一种元标记语言,允许用户定义自己的标记,因此,很可能出现名称重复的情
况。为了解决这个问题,W3C 在 1999 年 1 月颁布了名称空间(Name Space)标准。该标准对
名称空间的定义是:XML 名称空间提供了一套简单的方法,将 XML 文档和 URI 引用标记
的名称相结合,来限定其中的元素和属性名。由此可知它通过使用 URI,解决了 XML 文
档中标记重名的问题,从而确保任何一篇 XML 文档中使用的名字都是全球范围内独一无
二的。原则上一个不使用名称空间的 XML 文档是一个实用意义不大的文档,因为在全球
范围内很可能有和它同名的标记存在。
3.4.1 名称空间的声明
在使用名称空间之前,必须首先进行声明,名称空间的声明类似于前面元素的声明,
将一个唯一的标识符号指定到一个 URI 或其他合法字符串上,使用前面定义的标识符号作
为标记的前缀,表示一类标记的出处。
·55·
·56· XML 实用教程
注意在声明名称空间时可以将多个声明结合在一起,例如下面语句:
<book:bookinfo xmlns:book1="http://bestbook.jmu.edu.cn/cs/textbook"
xmlns:book2="http://cheapbook.jmu.edu.cn/ee/textbook">
名称空间具有继承性,也就是说,如果不明确声明子元素的名称空间,子元素将继承
父元素的名称空间声明。但要注意的是,在默认声明的名称空间范围内,所有的元素及其
子元素不加前缀,而在显示声明的名称空间范围内,所有的元素及其子元素必须加前缀。
【例 3.11】默认声明与显示声明名称空间的 XML 文档,代码如源程序 code3_11.xml 所示。
<?xml version="1.0" encoding="gb2312"?>
<book xmlns="http://bestbook.jmu.edu.cn/cs/textbook" xmlns:bo="
http://cheapbook.jmu.edu.cn/ee/textbook">
<bookinfo>
<title>计算机导论</title>
<author>丁跃潮等</author>
<price>19.7</price>
</bookinfo>
<bo:publish>
<bo:publisher>高等教育出版社</bo:publisher>
<bo:ISBN>7-04-014768-8</bo:ISBN>
<bo:pubdate>2004.6</bo:pubdate>
</bo:publish>
</book>
3.4.2 名称空间的范畴
名称空间的范畴就是名称空间起作用的范围。而范围就是声明该名称空间的元素及该
元素中所有的子元素,除非是在该元素的某一个子元素上又声明了相同的名称空间。
·56·
第3章 XML 基础 ·57·
上面的程序当中,用了同名的两个名称空间。第一个名称空间的作用范围是除了
<publish>标记块的整个文档内容,属于 http://book.jmu.edu.cn/it/textbook 名称空间。因为
<publish>标记块的内容中使用的名称空间为 http://bestbook.jmu.edu.cn/cs/textbook,它是一
个独立的区域,第一个名称空间的作用范围要去除该区域。
·57·
·58· XML 实用教程
<publish>
<publisher>高等教育出版社</publisher>
<ISBN>7-04-014768-8</ISBN>
<pubdate>2004.6</pubdate>
</publish>
<price>19.7</price>
</bookinfo>
</book>
<book id="001" category="文艺" amount="100" remain="80" discount="8.7">
<bookinfo>
<title>三国演义</title>
<author>罗贯中</author>
<publish>
<publisher>文艺出版社</publisher>
<ISBN>0-764-58007-8</ISBN>
<pubdate>1998.10</pubdate>
</publish>
<price>80.00 </price>
</bookinfo>
</book>
</books>
1. 建立根结点
·58·
第3章 XML 基础 ·59·
3. 给子元素输入内容
给子元素输入内容,只需在相应子元素的右侧空格内输入所需内容即可。如给 title 输
入内容,界面的主要部分如图 3.12 所示。
4. 给子元素增加属性
·59·
·60· XML 实用教程
5. 添加第二个 book 元素
·60·
第3章 XML 基础 ·61·
3.6 小 结
3.7 习 题
1. XML 文档中标记的使用有哪些需注意的方面?
2. 如何为一个 XML 文档添加注释?
3. 举例说明为什么要引入名称空间,如何声明名称空间。
4. 在 XML 文档中,若元素 teacher 的内容为:dingxiao asked“Can I help you?”,则
·61·
·62· XML 实用教程
该元素应该如何编写?
5. 使用 XML Spy 2005 编辑下列 XML 文档。
<?xml version="1.0" encoding="gb2312" ?>
<document>
<title>
user order list of E-shop
</title>
<order>
<customerID>XXXXXXXX</customerID>
<order_date>20040517</order_date>
<order_status>pending</order_status>
<item>
<bookID>001</bookID>
<quantity>1</quantity>
<order_item_status>pending</order_item_status>
</item>
</order>
</document>
·62·
第 4 章 XML 文档类型定义
教学提示:XML 的可扩展性表现在用户可以自己定义标记和标记之间的嵌套关系,而
DTD 就是进行这种定义的语言。它定义了文档的逻辑结构,规定了文档中所使用的元素、
实体、元素的属性、元素与实体之间的关系。根据 DTD 可检查 XML 文档中的数据,以验
证其是否符合规定和要求,这可以保证 XML 文档数据的正确性和有效性。本章介绍 DTD
的语法,包括元素、属性和实体的语法,结合例子给出 DTD 的使用方法并给出综合实例。
教学目标:了解 DTD 的作用,熟悉元素、属性及实体的运用,掌握引用 DTD 的方法,
能够为特定的系统设计标记语言。
4.2 DTD 元素
4.2.1 元素的基本类型
元素的基本类型大致可分为两种,一种称为简单型,另一种称为复合型。简单型具有
文本数据,即可析字符数据,该类型也称为上下文中的“#PCADTA”;复合型可以包含其
他元素和文本数据。
1. 简单型
“#PCDATA”(Parsed Character Data)表示标记的内容是可解析文本,所谓的可解析文
本就是非标记文本。用“#PCDATA”规范了的元素不能再包含子元素。例如 How do you do
是不包含标记的文本,而 How do you <list>do</list>就不是可解析的数据类型,因为其中包
含有标记<list>和</list>。另外 DTD 文档中不同元素定义的次序没有先后关系,但文档的语
法对大小写敏感。
“#PCDATA”的声明格式:
<!ELEMENT Element_Name (#PCDATA )>
【例 4.1】 “#PCDATA”的用法,代码如源程序 code4_1.xml 所示。
<?xml version="1.0" encoding="gb2312" ?>
<!DOCTYPE bookinfo [
<!ELEMENT bookinfo (title,author,publisher,price)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT publisher (#PCDATA)>
<!ELEMENT price (#PCDATA)>
]>
<bookinfo>
<title>计算机导论</title>
<author>丁跃潮等</author>
<publisher>高等教育出版社</publisher>
<price>19.7</price>
</bookinfo>
·64·
第4章 XML 文档类型定义 ·65·
图 4.1 “#PCDATA”的用法
图 4.2 复合型元素的用法
·65·
·66· XML 实用教程
4.2.2 元素的声明
1. 元素声明的基本语法
元素的声明格式:
<ELEMENT Element_Name Element_Defination>
其中,Element_Name 为声明的元素名称,Element_Defination 为元素内容格式的定义。
合法的元素声明语句如:
<!ELEMENT bookinfo (title,author,publish,price)>
<!ELEMENT publisher (#PCDATA)>
2. 空元素的声明
在第 3 章中已介绍了空标记的使用方法,那么在 DTD 中如何对与其对应的空元素进行
声明呢?其声明格式:
<ELEMENT Element_Name EMPTY>
例如下面的语句:
<ELEMENT hr EMPTY>
3. 不限定元素内容的声明
ANY 是 DTD 中使用很频繁的一个关键字,特别是对于文档根元素的声明。在定义一
个 DTD 文档时通常很难准确地确定一个元素是否具有子元素的情况,此时一般的做法是指
定该元素的子元素为 ANY 型(表示可以是任意的元素),这样在它之中可以包含任何数据、
任何声明的子元素及其数据和子元素的组合。
ANY 元素的声明格式:
<!ELEMENT Element_Name ANY>
而在文档刚开始定义时,并不明确将来的应用领域中会有多少个元素,所以唯一的做
法就是标记为 ANY 类型,表示可以包含任何元素和可解析数据。例如:
<!ELEMENT person ANY>
然后在文档的实际开发过程中再逐步完善该元素的子元素的具体定义,将 ANY 关键
字替换掉。
【例 4.3】 ANY 的用法,代码如源程序 code4_3.xml 所示。
<?xml version="1.0" encoding="gb2312" ?>
<!DOCTYPE bookinfo [
<!ELEMENT bookinfo ANY>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT publisher (#PCDATA)>
<!ELEMENT price (#PCDATA)>
]>
<bookinfo>
·66·
第4章 XML 文档类型定义 ·67·
<title>计算机导论</title>
<author>丁跃潮等</author>
<publisher>高等教育出版社</publisher>
<price>19.7</price>
</bookinfo>
·67·
·68· XML 实用教程
上面程序是一个不合法的文档,原因在于,标记<pubdate></pubdate>和<ISBN></ISBN>
的使用顺序与 DTD 中定义的顺序不一致。在一个标记后面的子标记列表中,子标记出现的
次序代表了将来 XML 文档中的子标记出现次序,而且这种次序不能被违背。
5. 可选择的子元素
有些时候,需要在两个或多个互斥的元素中进行选择。即多选一的情况,如一个人的
性别可以是男或女,两者中只能有一种情况。DTD 有专门的语法来处理这种情况,其语法
格式如下:
<!ELEMENT Element_Name(Child_Element1|Child_Element2|……)>
其中,“(Child_Element1|Child_Element2|…)”部分为选择性元素组合,具体使用时必
须要在这个列表中选择其一。
【例 4.6】 选择性元素列表的设定,代码如源程序 code4_6.xml 所示。
<?xml version="1.0" encoding="gb2312" ?>
<!DOCTYPE bookinfo [
<!ELEMENT bookinfo (title,author,publish,price)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT publish (publisher|ISBN|pubdate)>
<!ELEMENT publisher (#PCDATA)>
<!ELEMENT ISBN (#PCDATA)>
<!ELEMENT pubdate (#PCDATA)>
<!ELEMENT price (#PCDATA)>
]>
<bookinfo>
<title>计算机导论</title>
<author>丁跃潮等</author>
<publish>
<publisher>高等教育出版社</publisher>
</publish>
<price>19.7</price>
</bookinfo>
·68·
第4章 XML 文档类型定义 ·69·
6. 元素出现次数的控制
在 DTD 中定义一个元素的子元素无非是解决该元素可以包含什么元素,各个子元素的
出现次序以及能够出现的次数的问题。DTD 可以在一定程度上控制出现的次数。太精确太
复杂的控制是不必要的。如明确规定一个元素出现 3 次或 4 次,是容易使到的,使用上面
介绍的子元素列表的设定方法即可实现,但如果重复出现的次数较多时,这种方法就显得
十分笨拙,这时可用以下方法来对其进行控制。
(1) 一个元素可能出现一次,也可能不出现。这时可通过在元素名后面加上一个“?”
来实现。
(2) 一个元素可能不出现,也可能出现多次。这时可通过在元素名后面加上一个“*”
来实现。
(3) 一个元素可能出现一次,也可能出现多次,但至少也要出现一次。这时可通过在
元素名后面加上一个“+”来实现。
7. 元素组
在声明复合型元素的时候,可以使用括号将其部分子元素组合在一起,成为一个元素
组,该元素组在特性上与普通元素没什么区别,可以对其使用“?”、
“*”、
“+”等控制字符。
【例 4.7】 元素组的使用,代码如源程序 code4_7.xml 所示。
<?xml version="1.0" encoding="gb2312" ?>
<!DOCTYPE bookinfo [
<!ELEMENT bookinfo ((title,author,price)+)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT price (#PCDATA)>
]>
<bookinfo>
<title>计算机导论</title>
<author>丁跃潮等</author>
<price>19.7</price>
<title>三国演义</title>
<author>罗贯中</author>
<price>50.0</price>
</bookinfo>
·69·
·70· XML 实用教程
图 4.3 元素组的使用
图 4.4 较好的方案
·70·
第4章 XML 文档类型定义 ·71·
8. 混合型元素
还有另一种元素,其内容既可以为字符数据,也可以为子元素,这种元素称为混合型
元素。混合型元素的声明格式:
<!ELEMENT Element_Name(#PCDATA|Child_Element1|Child_Element2,…)>
混合型元素的存在破坏了文档的层次结构化,不利于应用软件对 XML 文档的处理,
在 XML 文档开发过程中,它可以作为一个不成熟的 DTD 文档,一步一步地在 XML 文档
中添加元素,边添加边测试其正确性,这时可将尚未处理的部分作为字符数据组织到一个
混合型元素中,以便使文档通过测试。但在文档最后完成时,要通过添加新元素的方法来
清除这种非结构化信息。
4.3 DTD 属性
4.3.1 属性的声明
在 DTD 中,属性的声明格式:
<!ATTLIST Element_name Attribute_name TYPE Default_value>
其中,<!ATTLIST>为属性声明的关键字,Element_name 为元素名,Attribute_name 为
属性名,TYPE 是属性类型,Default_value 为没有设定属性值时的默认值。
【例 4.9】 属性的声明,代码如源程序 code4_9.xml 所示。
<?xml version="1.0" encoding="gb2312" ?>
<!DOCTYPE bookinfo [
<!ELEMENT bookinfo (title,author,publisher,price)>
<!ATTLIST bookinfo ISBN CDATA "7-04-014768-8">
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT publisher (#PCDATA)>
<!ELEMENT price (#PCDATA)>
]>
<bookinfo ISBN="7-04-014768-8">
<title>计算机导论</title>
<author>丁跃潮等</author>
<publisher>高等教育出版社</publisher>
<price>19.7</price>
</bookinfo>
·71·
·72· XML 实用教程
图 4.5 属性的声明
在声明属性时有以下需要注意的事项。
(1) 可以多次为一个元素声明其中所包含的属性。如在 XML 文档中有如下语句:
<bookinfo id="001" bookcategory="文艺" >
</bookinfo>
属性声明可以为
<!ATTLIST bookinfo id CDATA "001">
<!ATTLIST bookinfo bookcategory CDATA "文艺" >
<!ELEMENT bookinfo (#PCDATA)>
(2) 属性的声明在文档中的次序没有严格的要求,可位于与其相连的元素声明之前或
之后。如在 XML 文档中有如下语句:
<bookinfo id="001" bookcategory="文艺" >
</bookinfo>
属性声明可以为
<!ATTLIST bookinfo bookcategory CDATA "文艺" >
<!ATTLIST bookinfo id CDATA "001">
<!ELEMENT bookinfo (#PCDATA)>
属性声明可以为
<!ATTLIST bookinfo bookcategory CDATA "文艺" >
<!ATTLIST bookinfo id CDATA "001">
<!ELEMENT bookinfo (#PCDATA)>
<!ATTLIST publish publisher CDATA "高等教育出版社" >
<!ATTLIST publish ISBN CDATA "7-04-014768-8">
<!ELEMENT publish (#PCDATA)>
·72·
第4章 XML 文档类型定义 ·73·
4.3.2 属性的类型
·73·
·74· XML 实用教程
5. ENTITY 与 ENTITIES 型
ENTITY 类型的属性提供了把外部二进制形式的文件(如.jpeg、.mp3 等)和外部不可解
析实体链接到 XML 文档的功能。因此其属性值也必须为不可解析的链接外部实际数据的
通用实体名。ENTITIES 类型属性的属性值可由多个不可解析的外部实体名称组成,各实体
名称之间使用空格隔开。
【例 4.11】 ENTITY 与 ENTITIES 的使用,代码如源程序 code4_11.xml 所示。
<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE customers [
<!ELEMENT customers (customer*)>
<!ELEMENT customer (username, password, picture)>
<!ELEMENT username (#PCDATA)>
<!ELEMENT password (#PCDATA)>
·74·
第4章 XML 文档类型定义 ·75·
·75·
·76· XML 实用教程
4.4.1 实体的概念
4.4.2 实体的分类
按照实体的具体内容来分类,实体可分为可解析与不可解析两类。可解析实体的具体
内容为简单的字符、数字、文本块,而不可解析实体的具体内容则为图片、声音等二进制
文件。
·76·
第4章 XML 文档类型定义 ·77·
按照逻辑存储来分类,实体可分为内部实体与外部实体两类。内部实体的内容是在文
档内部设定的;而外部实体则是一个外部独立的物理存储对象,如某个外部文件。
按照使用的范围来分类,实体可分为一般实体与参数实体两类。一般实体都用来构成
文档的具体内容,可出现在 XML 文档中,也可出现在 DTD 中;而参数实体只能出现在
DTD 中,不能出现在 XML 文档中。
1. 内部一般实体
内部一般实体就是在文档实体内部定义和使用的实体,其内容通常是一段文本字符。
这种实体要在 DTD 中通过 DTD 语句的定义,可以在 XML 文档中使用,也可在 DTD 中使
用。其定义的语法格式如下:
<!ENTITY Eentity_name "Replacement" >
·77·
·78· XML 实用教程
(2) 在语句中不能出现循环,如下面的语句即为非法的:
<!ENTITY thepub "北大&pub;">
<!ENTITY pub "出版社&thepub;">
2. 外部一般实体
所谓外部一般实体就是在文档实体以外定义的,要通过一个 URL 才能引用到的实体。
外部一般实体为独立的文件,可被多个文档所引用。正因为每一个完整的 XML 文档都是
一个合法的实体,所以 XML 通过对外部一般实体的引用,可以在一个 XML 文档中嵌入另
一个 XML 文档,或者将多个文档组合成一个文档。其定义的语法格式如下:
<!ENTITY Eentity_name "URL" >
可以通过下面的例子把它作为外部实体来引用。
【例 4.14】 外部一般实体的使用,代码如源程序 code4_14.xml 所示。
<?xml version="1.0" encoding="gb2312" standalone="no"?>
<!DOCTYPE bookinfo [
<!ELEMENT bookinfo (title,author,publish,price)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT publish (publisher,ISBN,pubdate)>
<!ELEMENT publisher (#PCDATA)>
<!ELEMENT ISBN (#PCDATA)>
<!ELEMENT pubdate (#PCDATA)>
<!ELEMENT price (#PCDATA)>
<!ENTITY pub SYSTEM "code4_14out.xml">
]>
<bookinfo>
<title>计算机导论</title>
<author>丁跃潮等</author>
&pub;
<price>19.7</price>
</bookinfo>
·78·
第4章 XML 文档类型定义 ·79·
在引用外部一般实体时,有以下几方面需注意。
(1) 因为在一个文档中需引用某些外部文件,所以该文档声明中的 standalone 属性不再
是默认值 yes,而应该为 no。
(2) 作为外部一般实体的文档,若使用的是 XML 的默认字符集即 UTF-8 或 UNICODE,
则可以在文档头部不进行 XML 声明,否则,必须有 XML 声明,且声明时,一定要说明
ecoding 属性。
3. 内部参数实体
内部参数实体是指在独立的外部 DTD 文档的内部定义和使用的实体,其内容为仅能为
DTD 而非 XML 文档内容的书写文本。这里提到参数实体与前面所讲的一般实体是有区
别的:
(1) 在引用形式上,一般实体的引用为“&Eentity_name;”,而参数实体的引用则为
“%Eentity_name;”
(2) 在引用范围上,一般实体可在 XML 文档中引用,也可在 DTD 中引用,而参数实
体只可在 DTD 中引用。
定义内部参数实体的语法格式如下:
<!ENTITY % Eentity_name "Replacement" >
4. 外部参数实体
外部参数实体是指在独立的外部 DTD 文档的外部定义和使用的实体,外部参数实体用
于将多个独立的 DTD 文档组合成一个大的 DTD 文档。定义外部参数实体的语法格式如下:
<!ENTITY % Eentity_name "URL" >
·79·
·80· XML 实用教程
<ISBN>7-04-014768-8</ISBN>
<pubdate>2004.6</pubdate>
</publish>
<price>19.7</price>
</bookinfo>
程序 code4_16_1.dtd 为
<?xml version="1.0" encoding="gb2312"?>
<!ELEMENT bookinfo (title,author,publish,price)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ENTITY % pub SYSTEM "code4_16_2.dtd">
%pub;
<!ELEMENT price (#PCDATA)>
程序 code4_16_2.dtd 为
<?xml version="1.0" encoding="gb2312" ?>
<!ELEMENT publish (publisher,ISBN,pubdate)>
<!ELEMENT publisher (#PCDATA)>
<!ELEMENT ISBN (#PCDATA)>
<!ELEMENT pubdate (#PCDATA)>
4.5 使用 DTD
4.5.1 内部 DTD
其中,<!DOCTYPE>为关键字,Root_Element_Name 为根元素名,[…]部分则为内部
DTD 定义语句。如例 4.1,即是一个包含内部 DTD 的 XML 文档。
4.5.2 外部 DTD
外部 DTD 就是有关文档定义的语句都被独立出来放在一个外部文件中,对其进行独立
的管理。跟据其内容的性质,可分为两种,一种是私有文件,指未公开的、属于某组织或
·80·
第4章 XML 文档类型定义 ·81·
4.5.3 混合 DTD
·81·
·82· XML 实用教程
4.6 综 合 实 例
books
图 4.7 图书信息管理系统的标记结构图
再根据以上标记结构图进行设计,设计过程如下:
(1) 分别设计作者、书籍、出版社信息的 DTD 语句;
(2) 使用外部实体的方式设计系统的 DTD 文档;
(3) 根据设计好的 DTD 文档,编写 XML 文档;
(4) 生成完整的 XML 文档。
4.6.1 DTD 片段
【例 4.18】 图书信息管理系统。
(1) 程序 code4_18_1.dtd,与作者相对应的 DTD 片段。
<?xml version="1.0" encoding="gb2312" ?>
<!ELEMENT authors (author*)>
<!ELEMENT author (a_name,sex,email*)>
<!ATTLIST author id ID #REQUIRED>
<!ATTLIST author ISBN IDREFS #REQUIRED>
<!ELEMENT a_name (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
<!ELEMENT email (#PCDATA)>
·82·
第4章 XML 文档类型定义 ·83·
4.6.2 系统 DTD 文档
·83·
·84· XML 实用教程
程序 code4_18.xml,XML 主文档。
<?xml version="1.0" encoding="gb2312" ?>
<!DOCTYPE volume SYSTEM "code4_18.dtd"[
<!ENTITY authors SYSTEM "code4_18_1.xml">
<!ENTITY books SYSTEM "code4_18_2.xml">
<!ENTITY publishers SYSTEM "code4_18_3.xml">
]>
<volume>
&authors;
&books;
&publishers;
</volume>
·84·
第4章 XML 文档类型定义 ·85·
4.7 小 结
·85·
·86· XML 实用教程
4.8 习 题
1. DTD 的作用表现在哪几个方面?
2. DTD 中的元素可分为哪两类,有何区别?
3. DTD 中的属性有几种不同类型的默认值,各种默认值之间有何区别?
4. 实体按其逻辑存储及使用范围,可分为哪几种类型?
5. 在引用内部一般实体时,要注意哪些问题?
6. 如图 4.9 所示,为其系统设计标记语言。
博物馆
油画 雕塑 古币
作者
作者
质量
币值
成画时间
使用年代
尺
寸
图 4.9 标记结构图
·86·
第 5 章 XML Schema 结构
5.1 Schema 概述
在 下 面 的 例 子 中 , 通 过 使 用 出 现 在 Schema 元 素 中 的 名 称 空 间 声 明 xmlns:xsd=
“http://www.w3.org/2001/XMLSchema”,使得模式文档中的每一个元素都有一个与 XML
Schema 名称空间相关联的名称空间前缀 xsd。尽管在语法上,可以使用任意的前缀形式,
但是,名称空间前缀 xsd 被约定用于表示 XML Schema 名称空间。由于使用同样的前缀,
所以同样的关联就会出现在内置的简单类型的名字中,例如 xsd:string。这种形式关联的目
的是用来表示当前的元素或简单类型属于 XML Schema 语言的内置定义,而不属于模式文
档作者自己的词汇表。为了在这里清楚并且简单地表示,仅提及元素的名字和简单类型名,
而忽略它们的前缀 xsd。
5.2.1 简单实例
·88·
第5章 XML Schema 结构 ·89·
(complexType)。而对于简单类型,只能有值,不能有子元素或者属性。同时还注意到 book
元素下的子元素,都按照一定的顺序排列,因此使用顺序元素(sequence element)来描述。
<xsd:element name="book">
<xsd:complexType>
<xsd:sequence>
顺序元素(sequence element)是一个定义子元素排列顺序的元素,在下面的章节,还将
介绍其他类似的元素,如选择(choice)和全选(all)。
接着定义 title 和 author,都是 xsd:string 类型的简单元素,因为没有属性(attributes)或
者子元素。xsd:string 是一个已经在名域中预定义了的 XML Schema 类型中的一个。
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="author" type="xsd:string"/>
<xsd:element name="price" type="xsd:integer" />
<xsd:element name="resume" type="xsd:string" />
<xsd:element name="recommendation" type="xs:string" />
最后,封闭所有剩下的元素。
</xsd:complexType>
</xsd:element>
</xsd:schema>
·89·
·90· XML 实用教程
符合某个模式的文档称为实例。实例可以根据特定的模式进行验证。需要声明 XML
文档的 Schema 实例名称空间(xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”),
并把名称空间映射到前缀 xsi。实例与模式之间有多对多的关系。一个模式可以描述多个有
效的实例(通过使用不同的根元素类型来实现),同样,一个实例也可以被多个模式描述。
例如一个实例可能拥有多个模式,它们有不同的验证级别。其中一个模式可能只验证结构,
而另一个模式则根据数据类型来检查每一个数据项。
1. Schema 的作用
Schema 文档用来验证 XML 文档的正确性,用来判断实例是否符合模式中所描述的所
有约束,涉及到检查实例中所有的元素和属性。
Schema 主要检验如下内容:
(1) 验证数据的显示格式是否正确及是否超出值的范围;
(2) 验证所有必需的信息都存在;
(3) 确保不同使用者对文档理解的方式相同。
除了对 XML 文档的验证外,Schema 文档还在一定程度上扩充实例:
(1) 为元素和属性添加默认值和固定值;
(2) 使具有简单类型的元素和属性值中的空白符规范化。
·90·
第5章 XML Schema 结构 ·91·
2. Schema 的引用
一个模式可能由多个模式文档构成。多个模式文档通过包含或导入机制来形成模式,
当其他模式文档与主模式文档具有相同的目标名称空间时,需要使用包含;当模式文档之
间各自拥有不同的目标名称空间时,需要使用导入。下面的例子建立一个单独用来验证实
例的模式文档。
【例 5.3】 关于多个模式文档通过包含实现定义的例子,代码如源程序 code5_3.xsd 所示。
<?xml version="1.0" encoding="gb2312" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://example.org/ord"
targetNamespace="http://example.org/ord">
<xsd:include schemaLocation="moreBookInfo.xsd"/>
<xsd:import namespace="http://example.org/ord"
schemaLocation="publish.xsd" />
<!--…-->
</xsd:schema>
则修改上面的实例为
<?xml version="1.0" encoding="gb2312" ?>
<book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://tempuri.org/book book.xsd"
·91·
·92· XML 实用教程
xmlns="http://tempuri.org/book"
isbn="0-764-58007-8">
<!--…-->
</book>
5.3.2 element 元素
其中,name 是元素类型的名称,必须是以字母或下划线开头,而且只能够包含字母、
数字、下划线、连接符及句号。type 属性是必要的,说明元素的数据类型。
下面的例子定义全局元素声明 author,为简单字符串类型。
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="author" type="xsd:string"/>
</xsd:schema>
·92·
第5章 XML Schema 结构 ·93·
5.3.3 设置默认值和固定值
默认值和固定值通过给空元素增加值的方式来扩展实例。如果文档中存在空的元素,
模式处理器根据模式文档的定义,会插入默认值或固定值。在 XSDL 中,默认值和固定值
分别通过 default 和 fixed 属性设置。两个属性只能出现其中之一,因为它们是互斥的。
如果元素为空,就填入默认值。下例中,声明了 city 元素,并指定了默认值为“佚名”。
<xsd:element name="author" type="xsd:string" default="佚名"/>
必须注意的是,元素声明中“空”的定义根据数据类型不同而有所不同。某些数据类
型允许空值,包括 string 等。任何允许空字符串值的类型,元素都不会认为是空的,从而
对于字符串类型元素,默认值不会被填充。相反,integer 数据类型的空元素通常会被认为
是空的,从而将填入默认值。此外,如果元素的 xsi:nil 属性被设置为 true,那么就不会插
入它的默认值。
<?xml version="1.0" encoding="gb2312"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2000/10/XMLSchema">
<xsd:element name="title" type="xsd:string"/>
·93·
·94· XML 实用教程
元素的默认值行为见表 5-1。
表 5-1 元素的默认值行为
固定值与默认值在相同的情况下添加,它们的差别仅在于如果元素拥有一个值,则该
值必须和固定值相等。当模式解析器确定元素值和固定值实际上是否相等时,会考虑到元
素的数据类型。price 元素的数据类型为 integer,所以整数 1 的所有形式在实例中都会被接
受,包括 01、+1 和周围包含空白符的 1。相反,对于 author 元素具有数据类型为 string,
字符串“01”是无效的,因为与字符串“1”并不相等。
<xsd:element name="author" type="xsd:string" fixed="1"/>
<xsd:element name="price" type="xsd:integer" fixed="1"/>
按照以上定义,元素的固定值行为见表 5-2。
表 5-2 元素的固定值行为
有效实例 无效实例
<price>1</price> <price>2</price>
<price>01</price> <author>01</author>
<price>+1</price> <author>+1</author>
<price></price> <author></author>
<price /> <author> </author>
<author>1</author> <author />
5.3.4 引用元素和替代
·94·
第5章 XML Schema 结构 ·95·
<xsd:element name="book">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="author" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
在这里还可以为某个定义的元素起一个别名,
主要是利用 element 元素中的 substitutionGroup
属性实现的。
方法如下:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="writer" type=xsd:string"
substitutionGroup="author" />
<xsd:element name="author" type="xsd:string"/>
<xsd:element name="book">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="author" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
或者:
<?xml version="1.0"?>
<book>
<writer>string</writer>
</book>
·95·
·96· XML 实用教程
5.4.1 创建属性
定义属性的方法如下:
<xsd:attribute name="isbn" type="xsd:string"/>
其中,use 属性用于指示属性是必需的还是可选的,它出现在属性引用而不是属性声明
中,因为它关系到属性在复杂类型中的出现,而不是属性本身。上面的例子定义的是全局
的属性定义方式,如果要在复杂类型里声明属性,可以参照下面的例子:
<xml ID="xmldata" SRC="code7_1.xml"></xml>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="book">
<xsd:attribute name="isbn" type="xsd:string" use="required"/>
<xsd:attribute name="amount" type="xsd:integer"/>
</xsd:complexType>
</xsd:schema>rbut
上面的例子描述了 isbn 和 amount 两个属性的局部声明,它们完全出现在复杂类型的
定义中。局部声明的属性名称,作用范围仅限于复杂类型内,在同一个复杂类型定义中,
两个属性使用相同的限定名称是非法的。只有当属性会被多个名称空间的多个元素声明使
用到时,才提倡将该属性声明为全局属性。
5.4.2 为属性指派类型
所有的属性声明都把属性指定为某种简单类型。所有的属性都具有简单类型而不是复
杂类型,因为它们本身不能有子元素和属性。
属性声明有 3 种方式:
(1) 在属性声明中通过用 type 属性指定命名简单类型。它可以是内置类型,也可以是
用户自定义类型。
(2) 通过指定 simpleType 子属性来指定匿名类型。
(3) 既没有 type 属性,又没有 simpleType 子属性,从而不指定特定类型。在这种情况
·96·
第5章 XML Schema 结构 ·97·
5.4.3 属性的默认值和固定值
对于属性来说,也可以通过默认值和固定值的方式增加未出现的属性来扩充实例。定
义和扩充的方式与元素一致。在 XSDL 中,默认值和固定值分别通过 default 和 fixed 属性
设置。两个属性只能出现其中之一,因为它们是互斥的。
如果属性在元素中默认,它的默认值将会被填入。如果属性出现,且包含任意值,它
将保持该值不变。下面的例子显示了 book 元素的声明,它包含一个 amount 属性,该属性
被指定了默认值。
<xsd:element name="book">
<xsd:complexType>
<xsd:attribute name="amount" type="xsd:integer" default="100"/>
</xsd:complexType>
</xsd:element>
固定值与默认值在基本一样的情况下被插入,区别在于,其值应和固定值相等。同时
也会考虑属性的类型。
<xsd:element name="book">
<xsd:complexType>
<xsd:attribute name="isbn" type="xsd:string" fixed="100"/>
<xsd:attribute name="amount" type="xsd:integer" fixed="100"/>
</xsd:complexType>
</xsd:element>
·97·
·98· XML 实用教程
5.5.1 简单类型
元素和属性声明都可以使用简单类型来描述数据类型。
1. 简单类型的种类
内建类型 定 义
time 24 小时格式的时间可根据时区调节
integer 整数,如 34
在前面一些例子中,有几个元素和属性被声明为简单类型。其中一些简单类型如 string
和 integer 是 XML Schema 中内置的类型,其他的一些则是源于(如果使用对象技术的语言
就是继承)内置的类型。
·98·
第5章 XML Schema 结构 ·99·
除此之外,新的简单类型可以通过从现有的简单类型(内置的简单类型以及源于内置简
单类型的简单类型)引出定义。通常,通过重新约束一个现有的简单类型来引出一个新的简
单类型。换句话说,新类型的合法值范围是现有类型的值范围的子集。使用 simpleType 元
素来定义和命名新的简单类型,使用 restriction 元素来指出现有的基类型,并且用它来标识
约束值范围的细节。
假设希望建立一个新的整数类型称为 myInteger,它的值范围为 10000~99999。那么定义
应当基于简单类型 integer,然后定义它的值范围为 10000~99999。为了定义 myInteger,这
样来约束 integer 的范围,示例如下:
<xsd:simpleType name="myInteger">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="10000"/>
<xsd:maxInclusive value="99999"/>
</xsd:restriction>
</xsd:simpleType>
这个例子显示了由一个基本类型定义和两个值域区间方面描述的组合,通过这 3 个要
素对 myInteger 实施定义。
2. 简单类型的命名定义
简单类型既可以为命名简单类型又可以为匿名简单类型。命名简单类型总是在全局定
义的,而且要求在模式的数据类型中具有唯一名称。类型的名称必须为 XML 无冒号名称,
即必须以字母或下划线开始,只能包含字、数字母、下划线、连字符和句点。如上面的例
子,简单类型名为 myInteger。
这种类型的模式构造非常直截了当,但有些不实用。特别是如果定义了许多只应用一
次而且包含非常少约束的类型,在这种情况下,一个类型应该能够被更简单的定义。这样
的简单定义通常的形式是一个省略了名称和外部引用开销的匿名类型。
在下面的示例中,publish 元素声明使用了匿名类型定义。一般来说,通过元素中是否
包含“type=”这个属性可以判断匿名属性定义(或者是匿名元素定义)。如果出现无名称的
类型定义,也可以认为是匿名属性(元素)定义。
<xsd:element name="publish">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="40"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
3. 简单类型的限制
每个简单类型都是从另一个简单类型派生而来的,则另一个简单类型称为基类型。可
以从原子类型,也可以从用户定义的简单类型派生。上面的例子都从内置的原子类型派生
成新的简单类型。所有新的简单类型都以某种方式限制其基类型的值空间。下面的例子从
简单类型种类例子中定义的 myInteger 类型进一步限制。
·99·
·100· XML 实用教程
<xsd:simpleType name="bookInteger">
<xsd:restriction base="xsd:myInteger">
<xsd:minInclusive value="23"/>
<xsd:maxInclusive value="2046"/>
</xsd:restriction>
</xsd:simpleType>
面 意 义
length 值的长度必须等于 x
totalDigits 有效数字的位数必须小于等于 x
fractionDigits 小数位数必须小于等于 x
enumeration x 是一个有效值
pattern x 是值可以匹配一个正则表达式
对每个内置的原子类型来说,都有一套定义时可用的面。如果某个面适用于某种原子
类型,那么也适用于由该类型派生的简单类型。这里有必要举例说明枚举的简单类型定义,
下面的例子定义了一个简单类型 category,用于说明书籍的类别。
<xsd:simpleType name="category">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="小说"/>
<xsd: enumeration value="散文"/>
<xsd: enumeration value="传记"/>
<xsd: enumeration value="诗歌"/>
<xsd: enumeration value="武侠"/>
<xsd: enumeration value="纪实"/>
</xsd:restriction>
</xsd:simpleType>
4. 列表类型
除了使用简单类型中描述的原子类型,XML Schema 还定义了其他两种简单类型:列
表类型和联合类型。
列表类型由一组原子类型组成,因此它的每一个部分(原子)本身都是有意义的,定义
时以空格隔开原子值的列表。举例来说 category 是个列表类型。这个类型的元素将是
NMTOKEN 的列表,不同的 NMTOKEN 值使用空格分隔,如“小说 散文 传记”。XML
·100·
第5章 XML Schema 结构 ·101·
一些用于描述的参数能够被应用到列表类型的定义中,它们是 length、minLength、
maxLength 和 enumeration。举例来说,如果想定义一个列表类型,这个列表类型正好包含
了 6 个分类项名。首先从 category 类型定义一个新的列表类型,称为 cateList,然后通过限
制 cateList 导出只有 3 个项的 threeBookCate 类型。具体的定义如下:
<!-- Schema Fragment -->
<xsd:simpleType name="cateList">
<xsd:list itemType="category"/>
</xsd:simpleType>
<xsd:simpleType name="threeBookCate">
<xsd:restriction base="cateList">
<xsd:length value="3"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:element name="threeBookCategory" type="threeBookCate"/>
·101·
·102· XML 实用教程
类型)的实例。与之相比较,一个联合类型(Union Type)包含了多个原子类型或者列表类型,
而应用了联合类型的元素或属性,它们的值可以是联合类型中所包含的这些原子类型或列
表类型中的任何一个类型实例。为了说明这一点,建立一个用于表示学生成绩的由评定等
级或者数字列表的联合类型。gradeUnion 联合类型由一个原子类型和一个列表类型构成。
<!-- Schema Fragment -->
<xsd:simpleType name="gradeUnion">
<xsd:union>
<xsd:simpleType name="scoreType">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="0"/>
<xsd:maxInclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="gradeType">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="优"/>
<xsd:enumeration value="良"/>
<xsd:enumeration value="及格"/>
<xsd:enumeration value="不及格"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:union>
</xsd:simpleType>
组成联合类型的简单类型称为它的成员类型。成员类型必须是简单类型,不存在复杂类
型的联合。除了直接用简单类型来规定成员类型外,还可以使用 union 元素的 memberTypes
属性来规定成员类型。假定已经在模式文档的其他地方定义了 gradeType 和 scoreType,改
写上面的例子:
<!-- Schema Fragment -->
<xsd:simpleType name="gradeUnion">
<xsd:union memberTypes="scoreType gradeType"/>
</xsd:simpleType>
<xsd:element name="stuScore" type="gradeUnion"/>
5.5.2 复杂类型
复杂类型的元素拥有子元素和属性,还可以有字符内容。复杂类型和简单类型之间最
根本的区别就是:复杂类型的内容中可以包含其他元素或属性,但简单类型既不能包含子
·102·
第5章 XML Schema 结构 ·103·
元素,也不能带有任何属性。复杂类型有 4 种不同的内容类型:简单类型、纯元素类型、
混合类型及空类型。下例中给出了具有复杂类型的元素:book 是带有属性的元素、bookinfo
是包含子元素的纯元素复杂类型、chapter 是混合类型的复杂类型元素以及内容为空的元素
price。它们分别属于下面要描述的 4 种不同的内容类型。
<?xml version="1.0" encoding="gb2312" ?>
<book isbn="0-764-58007-8">no.1</book>
<bookinfo>
<title>三国演义</title>
<author >罗贯中</author>
</bookinfo>
<chapter >宴桃园豪杰三结义 斩黄巾英雄首立功
<para>话说天下大势,分久必合,合久必分。</para>
</chapter>
<price value="30"/>
纯元素内容只允许有子元素,而没有字符数据内容。下例显示了具有纯元素内容的
bookinfo 元素,它有两个子元素:title 和 author。
·103·
·104· XML 实用教程
<bookinfo>
<title>三国演义</title>
<author>罗贯中</author>
</bookinfo>
可以按如下方式进行定义:
<xsd:compleType name="bookinfoType">
<xsd:sequence>
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="author" type="xsd:string"/>
</xsd:sequence>
</xsd:compleType>
混合内容既允许有字符数据又允许有子元素。经常用于字母和文档等形式的自由文本。
下例中显示了具有混合内容的 chapter 元素。chapter 元素中直接包含字符数据以及子元
素 para。
<chapter>宴桃园豪杰三结义 斩黄巾英雄首立功
<para>话说天下大势,分久必合,合久必分。</para>
</chapter>
空内容既不允许有字符数据也不允许有子元素。带有空内容的元素通常在属性中具有
值。有某些情况下,甚至可以没有属性,但空内容的元素存在本身就有意义。如 XHTML
中的<br/>元素就表示一个新行。
<price value="30"/>
要定义空内容元素的类型时,只需指定属性,不用做其他内容的说明。
<xsd:compleType name="priceType">
<xsd:attribute name="value" type="xsd:integer">
</xsd:compleType>
2. 利用组合器控制结构
模式组允许把子元素声明或引用组合起来,从而构建更有意义的内容模型。模式组共
有 3 种:sequence、choice 和 all。
sequence 组合器,定义了一列元素并且必须按照模式中指定的顺序显示,所有子元素。
如果出现的话,都必须按照该顺序出现。示例如下。
·104·
第5章 XML Schema 结构 ·105·
<xsd:element name="book">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="author" type="xsd:string"/>
<xsd:element name="publisher" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
choice 组合器用来声明只有一个相容元素必须出现,用于互斥情况。示例如下。
<xsd:element name="book">
<xsd:complexType>
<xsd:choice>
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="author" type="xsd:string"/>
<xsd:element name="publisher" type="xsd:string"/>
</xsd:choice>
</xsd:complexType>
</xsd:element>
<book>
<author>罗贯中</author>
</book>
·105·
·106· XML 实用教程
all 组合器用来表示符合元素声明的所有元素都应该出现(以任何顺序)且只能出现一
次。all 组合器与 choice 和 sequence 的不同之处在于:
(1) 只能包含元素声明和引用,而不能包含其他组。
(2) 不能出现多次。对于所包含的每个子元素,maxOccurs 必须为 1,而 minOccurs 只
可以为 0 或 1。不能出现在其他模式组中。all 组必须在复杂类型的最高层。
示例如下。
<xsd:element name="book">
<xsd:complexType>
<xsd:all>
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="author" type="xsd:string"/>
<xsd:element name="publisher" type="xsd:string"
minOccurs="0"/>
<xsd:element name="price" type="xsd:integer" minOccurs="0"/>
</xsd:all>
</xsd:complexType>
</xsd:element>
<book>
<title>三国演义</title>
<author>罗贯中</author>
</book>
5.6.1 命名冲突
·106·
第5章 XML Schema 结构 ·107·
5.6.2 使用前缀解决命名冲突问题
·107·
·108· XML 实用教程
为了避免前缀冲突,可以使用如下的前缀声明。
f="http://www.example.org/html"
h="http://www.example.org/furniture"
5.6.3 使用名称空间
前缀只是起着名称空间的代理作用。名称空间的名称是 URI,而不是前缀,在比较两
个元素时,解析器是根据 URI 来识别它们的名称空间,而不是根据前缀识别。上面的例子
则可以与不同的名称空间关联到一起。
<h:table xmlns:h="http://www.example.org/html">
<h:tr>
<h:td>Apples</h:td>
<h:td>Bananas</h:td>
</h:tr>
</h:table>
名称空间的声明将一个全局名称(URI)跟元素的名称联系在一起。URI 只作为标识符。
仅就作为 XML 名称空间来说,URI 不必是有效的。也就是说,它不必指向任何位置。XML
名称空间只将它们作为字符串处理。比较是逐个字符进行的,因此,下面的两个 URI 是不
同的,虽然指向同一个文档。
http://www.example.org
http://example.org
而且名称空间是区分大小写的。即使仅有大小写区别,也会被解析为不同的 URI。
大多数的 URI 都是 URL 或 Internet 地址。可能指向网络上的某个文件、用户电子邮箱
(mailto:branch@example.org)或者是新闻组(news:comp.exmaple.xml)。
目前正在开发另一种形式的 URI,称为 URN(Uniform Resource Name)。两者的区别在
·108·
第5章 XML Schema 结构 ·109·
5.6.5 名称空间的作用域
名称空间声明可以出现在文档的任何开始标记中,它的作用域是它在其开始标记中出
现的元素以及其所有子元素等。
<bk:book xmlns:bk="http://www.example.org/2005/book">
<bk:title>三国演义</bk:title>
<bk:author >罗贯中</bk:author>
<bk:price >80.00 </bk:price>
<bk:recommendation>经典好书</bk:recommendation>
<ph:publish xmlns:ph="http://www.example.org/2005/publish">
<ph:publisher>文艺出版社</ph:publisher>
<ph:pubdate>1998.10</ph:pubdate>
</ph:publish>
</bk:book>
上面的示例中声明了两个名称空间,bk 是顶层元素声明的,因此对所有元素都是有效
的。ph 是为 publisher 元素声明的,只对它的子元素有效。但是,如果还有一个 book 元素,
它的子元素 publisher 使用了 ph 前缀,则是不合法的名称空间,因为超出了其作用域。一
般来说,最好把所有名称空间声明都放到根元素的开始标记中。这样可以一下子看到文档
的所有名称空间,对于它们的作用域也不会混淆。
1. 目标名称空间
每一个XSDL 模式文档都可以是一个名称空间,这称为它的目标名称空间(Target
Namespace)。每个被全局声明所声明和定义的元素、属性、类型或组等都与该目标名称空
间有关。下例中声明了 http://www.example.org/2005/book 的目标名称空间。
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.example.org/2005/book"
targetNamespace="http://www.example.org/2005/book">
<xsd:element name="book"type="BookType"/>
<xsd:complexType name="BookType">
<xsd:sequence>
<xsd:element name="title" type="xs:string" />
<xsd:element name="author" type="xs:string"/>
<xsd:element name="price" type="xs:integer" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
而下面的例子显示相应的元素如何出现在一个实例中。
·109·
·110· XML 实用教程
<bk:book xmlns:bk="http://www.example.org/2005/book">
<bk:title>三国演义</bk:title>
<bk:author>罗贯中</bk:author>
<bk:price>80.00 </bk:price>
</bk:book>
·110·
第5章 XML Schema 结构 ·111·
有时,把前缀映射到所有名称空间也是可以的,这样整个文档也非常清晰。
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:bk="http://www.example.org/2005/book"
targetNamespace="http://www.example.org/2005/book">
<xsd:element name="book" type="bk:BookType"/>
<xsd:element name="title" type="xsd:string"/>
<xsd:complexType name="BookType">
<!--…-->
</xsd:complexType>
</xsd:schema>
5.7.1 建立根结点
·111·
·112· XML 实用教程
图 5.2 添加一个元素并设定元素类型
图 5.3 添加子结点信息
·112·
第5章 XML Schema 结构 ·113·
图 5.4 定义好的书籍文档结构
·113·
·114· XML 实用教程
5.8 小 结
·114·
第5章 XML Schema 结构 ·115·
5.9 习 题
那么对于下面的实例,哪些是有效的?
<size>1</size>
<size>2</size>
<size>+1</size>
<name>1<name/>
<name>+1<name/>
·115·
·116· XML 实用教程
</ByLine>
<DateLine>April 30, 2005</Dateline>
<body>Content of story goes here…</body>
<stats>
<submitted>2005-03-02</submitted>
<wordCount>1523</wordCount>
</stats>
</article>
·116·
第 6 章 层叠样式表
教学提示:XML 为存储结构化数据提供了强大的方法,但是它没有提供关于数据如何
显示的信息,这实际上是 XML 的优点——数据的结构完全与数据表示无关。当有必要表示
格式化 XML 文件中的数据时,格式化的详细信息放置在 CSS 中。
教学目标:理解 CSS 的概念,掌握 CSS 的方法,掌握 CSS 与 XML 结合的方法,学会
综合运用 CSS。
6.1 CSS 简介
1. CSS 的基本语法
在 XML 中,组成文档的单元是一个个的元素,因此元素的概念对于 XML 来说非常重
要。而在 CSS 中,几乎看不到 XML 语法的任何痕迹(当然,CSS 本来就不是为 XML 设计的)。
然而,CSS 也有自己的组成结构,而且也有类似 XML 中元素的结构单元。在这里,暂且
就叫这种结构单元为 CSS 元素。
CSS 的规则通过属性与属性值来共同设定。属性名称是 CSS 的关键字,如 font-family(字
体)、font-size(文字大小)、display(显示属性)和 color(颜色)等。属性用于指定元素某一方面
的特性,而属性值则用于指定元素特性的具体特征。
样式表的建立要符合 CSS 规则,它们一般被定义成以下形式的句法。
标志{标志属性 1:属性值 1;标志属性 2:属性值 2;标志属性 3:属性值 3;…}
其中标志不带尖括号,如 P、Div、Table 等,而不是<P>、<Div>以及<Table>。
“标志属性:属性值,”是一一对应的,每个属性与属性值对之间用分号隔开。有一点
要说明的是,在 CSS 中对属性设置与脚本语言中对属性设置有一点不同,即属性名称的写
法,在 CSS 中,凡属性名为两个或两个以上的单词构成时,单词之间以“-”隔开,比如,
背景颜色属性 background-color;而在脚本中,对象属性则连写成 backgroundColor,第二个
单词首字母大写,如有 3 个单词则第三个单词首字母也要大写。
下面是样式表的一个简单的例子:
P{background-color:red;font-size:12pt;color:black}
上面分别设置了背景色、字体大小以及字体颜色等。为了看起来直观一些,还可以
写成:
P{background-color:red;
font-size:12pt;
color:black}
·118·
第6章 层叠样式表 ·119·
P1{font-size:16pt;
font-family:'宋体';
font-style:italic}
由于没有对应的 CSS,浏览器根本不知道应该如何处理元素内容的显示方式,所以只
能原样显示。
3. 使用 CSS 的 XML 文件
XML 文档中通过引用外部 CSS 来定义文档的表现形式。大部分 XML 文档都采用这种
方式,这也与 XML 的内容与形式分开的原则相一致。具体实现的方法是,在 XML 文档的
开头部分写一个关于样式单的如下声明语句:
<?xml-stylesheet type="text/css" href="mycss.css" ?>
这样一来,按照声明语句的指示,该文档在浏览器上的表现方式就由样式文件 mycss.css
·119·
·120· XML 实用教程
所决定了。
这个命令说明了该 XML 文档使用 CSS,CSS 文件为本地目录的 mycss.css。
当然,也可以使用完整的 URL 指定 CSS 文件,如下面这个例子:
<?xml-stylesheet type=" text/css" href=http://www.myhome.com/file/mycss.css ?>
现在,定义 code6_2.css。
@charset "gb2312";
name{display:block;
font-family: 黑体;
font-size: 20pt;
letter-spacing:10pt;
text-align:center; }
writer{display:block;
font-family: 魏碑;
font-size:10pt;
font-weight:bold;
letter-spacing:10pt;
line-height:40pt;
text-align:center;
color: Black; }
content{display:block;
font-family: 隶书;
font-size: 20pt;
font-weight:bold;
line-height: 30pt;
letter-spacing:10pt;
text-align:center;
color: Black;}
·120·
第6章 层叠样式表 ·121·
6.2 设置字体属性
通常,XML 文档中最主要的信息是由文本信息构成的。换句话说,文字和符号是存储
信息的主要载体。现在就来学习 CSS 中控制文字格式的相关语法。
1. font 属性的分类
font 属性通常用于设置指定字体的风格、大小、亮度等参数。该属性在 XML 样式表分
类中属于通用字体类,由 CSS 定义。font 属性的常见子属性见表 6-1。
font 属性 说 明
font-family 指定字体的字型
font-style 指定字体的风格
font-weight 指定字体的亮度
font-variant 指定字体全为大写字母
font-size 指定字体的大小
font-stretch 指定字体的压缩或拉伸方式
·121·
·122· XML 实用教程
2. font 属性的用法
与常见的 CSS 属性设置类似,font 属性的使用示例如下:
element{font-style:italic;font-size: "20pt"; font-family: "楷体_gb2312";}
font-style 属性 说 明
读者阅读的普通文本就是正常体。倾斜字体(oblique)的文本十分类似于斜体文本。但
是,绝大多数情况下,倾斜字体的文本是由计算机根据简单的算术运算,使正常的文本倾
斜一定的角度实现的。用斜体字印刷文本通常是为了美观。
5. 字体亮度 font-weight 属性
font-weight 属性设置字体的粗体程度,用于决定文本以多黑(粗)或多浅(细)显示文本。
font-weight 属性的参数值见表 6-3。
font-weight 属性设置字体的粗体程度,常用取值为 bold 和 normal,例如:
element{font-weight:bold}
·122·
第6章 层叠样式表 ·123·
font-weight 属性 说 明
element{font-weight:900}
element{font-weight:200}
font-variant 属性 说 明
7. 设置字体大小 font-size 属性
font-size 属性用于指定字体的相对或者绝对大小。font-size 属性的参数值见表 6-5。
font-size 属性 说 明
整数+pt 表示使用指定的像素大小显示字体,pt 表示像素(如 20pt、35pt)
整数+% 表示当前元素使用字体大小是前一个元素大小的百分数(如 40%、150%)
large 表示使用比父元素大一号的字体
x-small 表示使用字体比 small 字体小 1.2 倍
xx-small 表示使用字体比 x-small 字体小 1.2 倍
x-large 表示使用字体比 large 字体大 1.2 倍
xx-large 表示使用字体比 x-large 字体大 1.2 倍
medium 表示使用标准字体大小显示
·123·
·124· XML 实用教程
8. 文本属性
在 CSS 中,表示文本外观的属性有 8 个,使用说明见表 6-6。
例 如 : name{letter-spacing:.5em} 表 示 增 加 字 符 间 距 为 文 本 高 度 的 1/2 。 Name
{letter-spacing:-.5pt}表示减少字符间距 0.5 磅。若将 letter-spacing 值设为 normal 则表示使用
正常的字符间距。
表 6-6 文本外观的属性
文本属性 说 明
letter-spacing 设置字符间隔,可以增加或减少字符之间的间距
word-spacing 设置字符间隔。其使用方法与 letter-spacing 类似
vertical-align 设置或检索对象内容的垂直对齐方式
作用于块元素,用来设置块中文本的对齐方式,取值为:left(左对齐)、right(右
text-align
对齐)、center(居中)、justify(两端对齐)
设置第一行缩进距离。如 name{text-indent:2em},表示第一行缩进两个字的
text-indent
长度
inline-height 控制文本连续行之间的距离,可以用来调整文本垂直线的距离
设置显示文本的字母大小写的显示形式。取值关键字为:capitalize,首字母
text-transform 大写;uppercase,所有字母都大写;lowercase,所有字母都小写;none,
不改变字母的大小写状态
声明文本是否有划线,常用来装饰链接。取值关键字为:overline,有上划
text-decoration 线;line-through,有穿过文本的删除线;blink,使文字闪烁;underline,有
下划线;none,没有任何划线
·124·
第6章 层叠样式表 ·125·
6.2.2 实例
下面是一个使用字体属性的例子。
【例 6.3】 用 CSS 显示文档 code6_3.xml,CSS 文件为 code6_3.css。
<?xml version="1.0" encoding="gb2312" ?>
<?xml:stylesheet type="text/css" href="code6_3.css"?>
<poem>
<name>望庐山瀑布</name>
<writer>唐.李白</writer>
<contentA>日照香炉升紫烟</contentA>
<contentB>遥看瀑布挂前川</contentB>
<contentC>飞流直下三千尺</contentC>
<contentD>疑是银河落九天</contentD>
</poem>
·125·
·126· XML 实用教程
font-weight: bolder;}
contentC{display:block;
font-family: 隶书;
font-size: 20pt;
font-weight:bold;
line-height:100%;
letter-spacing:10pt;
text-align:center;
color: Black;
font-size:300%;
font-weight: 700;}
contentD{display:block;
font-family: 隶书;
font-size: 20pt;
font-weight:bold;
line-height:100%;
letter-spacing:10pt;
text-align:center;
color: Black;
font-size:400%;
font-weight: 900;}
图 6.3 使用字体属性的例子
本实例的目的是让大家熟悉各种与字体相关的属性设置的特点和用法。在 实 例
code6_3.css 文件中没有进行其他操作,只分别针对诗里不同的文字样式要求进行了属性的
字体设置,并综合运用了字体、字型、风格等文字修饰技术,可以说是字体设置方面知识
点的一个整合。
字体样式属性的设置操作起来是比较简单的。
·126·
第6章 层叠样式表 ·127·
6.3 设置色彩和背景图像属性
在互联网中,没有色彩的页面即使做得再精致也缺乏吸引力。CSS 中对于色彩和图像
的设定功能也是比较完善和强大的,接下来学习在 CSS 中添加色彩属性的定义。
6.3.1 定义前景色
表 6-7 颜色名称参数对应色彩数值
2. color 属性的用法
color 属性的语法比较简单,下面通过一个示例来进行介绍。
例如,有这样一个很简单的 XML 文档示例,内容是显示一段唐诗。现在,使用 color
属性对该 XML 文档进行前景色彩的设定,如例 6.4 的程序代码。
【例 6.4】 文档 code6_4.xml 的显示,使用的 CSS 文件为 code6_4.css。
<?xml version="1.0" encoding="gb2312" ?>
<?xml:stylesheet type="text/css" href="code6_4.css"?>
<poem>
<name>望庐山瀑布</name>
<writer>唐.李白</writer>
·127·
·128· XML 实用教程
<contentA>日照香炉升紫烟</contentA>
<contentB>遥看瀑布挂前川</contentB>
<contentC>飞流直下三千尺</contentC>
<contentD>疑是银河落九天</contentD>
</poem>
6.3.2 定义背景色
1. background 属性集
background 属性集用于对指定元素的背景进行设置,如色彩、图案等,见表 6-8。
2. 设置背景颜色
background-color 属性用于设置指定元素的背景颜色,其参数值有以下几种(与 color 属
性类似)。
·128·
第6章 层叠样式表 ·129·
background 属性 说 明
background-color 用于对指定元素设置背景颜色
background-image 用于对指定元素设置背景图案
background-repeat 在背景图案小于指定元素的情况下,是否使用重复填充图案
background-attachment 用于指定设置的背景图案在元素滚动时是否一起滚动
background-position 用于指定背景图案的起始位置
1) “#RGB”
符号“#”加上表示 RGB 色彩的 3 位十六进制整数(如“#EB2”、“#FFF”等),其中
的 R、G、B 分别代表红色、绿色、蓝色,每个十六进制数字从 0 到 f 取值,数值越高表示
相应的色彩越浅,如白色就表示为“#FFF”。
2) “#rRGGBB”
符号“#”加上表示 RGB 色彩的 6 位十六进制整数(如“#0080FF”等),其中的每个
两位十六进制数从 00 到“ff”取值。同样是数值越高对应的色彩越浅,如白色就表示为
“#FFFFFF”。
3) RGB(RRR,GGG,BBB)
直接用 3 个 3 位十进制整数(如 RGB(010,128,256))表示,每个 3 位的十进制数从 000
到 256 取值。
4) RGB(r%,g%,b%)
直接用 3 个百分数表示(如 RGB(15%,20%,90%)),每个百分数取值从 0.0%到 100.0%,
数值越大表示对应色彩越浅。如白色就表示为 rgb(100.0%,100.0%,100.0%)。
5) 颜色名称
使用 red、blue、yellow 等表示颜色的英文字符指定元素的色彩。
3. 设置背景图案
background-image 属性用于设置指定元素的背景图案,其参数值用以下两种方式指定。
(1) background-image:定义背景图形。取值为 none、url,当取值为 none 时表示不用
图形作为背景,当取值为 url 时表示提供图形文件的 URL 地址。
(2) 直接的图像文件名称(如 image001.gif),这里是指和 CSS 文件在同一目录下的文件。
4. 设置背景图案重复方式
background-repeat 属性用于指定背景图案的重叠覆盖方式,其参数值有以下几个。
(1) repeat:使用背景图案完全填充元素大小的空间。
(2) repeat-x:使用背景图案在水平方向从左到右填充元素大小的空间。
(3) repeat-y:使用背景图案在竖直方向从上到下填充元素大小的空间。
(4) no-repeat:不使用背景图案重复填充元素。
·129·
·130· XML 实用教程
5. 设置背景图案滚动方式
background-attachment 属性用于背景图案的滚动方式,在需要设置的元素占用的空间
在浏览器中使用滚动条才能完整看到的时候,可以用该属性指定在文字元素滚动的同时,
背景图案是否一起滚动。
background-attachment 属性的参数值有以下两个。
(1) scroll:表示在文字页面滚动时,背景一起滚动。
(2) fixed:表示在文字页面滚动时,背景固定不滚动。
6. 设置背景图案起始位置
background-position 属性用于指定需要设置的背景图案的具体起始位置。
(1) top:表示背景图案位于指定元素的顶部。
(2) center:表示背景图案位于指定元素的中部。
(3) bottom:表示背景图案位于指定元素的底部。
(4) left:表示背景图案位于指定元素的左部。
(5) right:表示背景图案位于指定元素的右部。
background-position 属性还有两个子属性:
(1) background-position-horizontal 子属性用于控制背景图案的水平位置。
(2) background-position-vertical 子属性用于控制背景图案的竖直位置。
6.4 设置边界属性
在 CSS 中,提供了方框边界属性来对元素中文本的版面进行设置,它主要提供如下 3
种功能。
(1) 设置元素在文件中的位置;
(2) 在元素周围添加边框,并设置边框的样式、大小;
(3) 控制相邻元素的位置。
本节主要对 CSS 中的方框边界属性进行介绍。
6.4.1 设置边框属性
·130·
第6章 层叠样式表 ·131·
border-style 属性 描 述
none 不显示边框,为默认值
dotted 点线
dashed 虛线
solid 实线
double 双线
groove 3D 陷入线
ridge 3D 山脊状线
inset 使页面有沉入感
outset 使页面有浮出感
border-width 属性 描 述
thin 细线边框
medium 中等边框
thick 粗线边框
例如:
resume
{ border-style:solid;
border-width:thick}
resume
{ border-style:solid dotted solid dotted;
border-width:thick 1px thick 1px}
·131·
·132· XML 实用教程
6.4.2 设置填充属性
在边框属性设置完后,元素与边框的距离会过于接近,因此需要添加填充属性,使得
边框与元素之间的距离不会太靠近,从而提高显示时的美感。
要给元素与边框添加填充,可对以下属性进行设置:padding-top、padding-bottom、
padding-left、padding-right,依次表示给元素与顶、底、左、右边框添加填充,例如:
resume
{ border-style:solid;
border-width:thick
border-color:red
padding-top:1em
padding-bottom:1em
padding-left:50%
padding-right:50%
}
这个例子给元素与边框添加填充符,在元素与顶边框、底边框之间添加宽度为元素宽
度一倍的填充,在元素与左边框、右边框之间添加宽度为元素宽度的 50%的填空。从上面
的例子可以看到为元素与边框添加填充符时可以是具体的尺寸值,也可以是元素的父元素
宽度的百分比。此外,若添加填充符 padding-top、padding-bottom、padding-left、padding-right
四个属性取值一样时,可缩写成只设置 padding 的属性。
resume
{ border-style:solid;
border-width:thick
border-color:red
padding-top:1em
padding-bottom:1em
padding-left:1em
padding-right:1em
}
可简写为
resume
{ border-style:solid;
border-width:thick
border-color:red
padding:1em
}
·132·
第6章 层叠样式表 ·133·
6.4.3 设置大小属性
6.4.4 设置定位属性
在默认的条件下,相同父元素的块级元素是一个紧挨一个显示的,因此需要设置定位
属性来控制相邻元素的位置。在 CSS 中,可使用 float 和 clear 来控制相邻元素的位置。定
位属性控制相邻元素位置的含义见表 6-11。
表 6-11 定位属性的含义
定位属性 描 述
float 设置文本相对于元素的位置。取值为:left、right、none
left 下一个文本位于元素的左边
right 下一个文本位于元素的右边
none 默认值,下一个文本紧接着显示出来
clear 设置浮动元素相对于元素的位置。取值为:left、right、none、both
left 浮动元素位于元素的左边
right 浮动元素位于元素的右边
both 浮动元素位于元素的两侧
6.4.5 设置页面边界属性
·133·
·134· XML 实用教程
6.5.1 @规则
CSS2 中提供@规则用来完成某项任务,而不是选择元素或把一些样式应用于这一元
素。在 CSS2 中提供的@规则有 5 种,分别如下。
1. @page
@page 规则选择页面框,把样式应用于页面。通过它可以设计页面框大小、页面区域
和页边距等。@page 规则无法理解以 em 和 ex 为单位的尺寸,但对于所有的其他度量单位
是可以解析接受的。用于设置页边距的百分数也是总页面框的百分数。页边距可为负值,
表示把内容放在通常应用程序或打印机可访问的区域之外。在大多数情况下,只保留可见
或可打印区域内的信息。
2. @import
@import 规则把指定的外部样式单嵌入到现有的样式单中。这样可以根据多个较小、
较容易理解的片断生成大样式单。导入的样式单使用.css 扩展名。例如,下面的规则导入
mycss.css 文件:
@import uri(mycss.css);
3. @media
@media 规则把用于某种媒体的特性组合起来成为样式规则。CSS2 可为显示在不同媒
体中的相同元素指定不同的样式。CSS2 中可以将只准备用于一种媒体的多个样式规则放入
一条指明媒体名的@media 规则中。在一篇文档中,@media 规则的数量与指定的媒体类型
一样多。
CSS2 识别如下 10 种媒体类型。
(1) all:所有的设备。
(2) aural:语音合成器。
(3) braille:用于有视觉障碍的盲文反馈设备。
(4) embossed:分页盲文打印机。
·134·
第6章 层叠样式表 ·135·
4. @font-face
@font-face 规则用来描述样式单中其他地方使用的字样。可提供字体名、URL 和有关
字体点阵的信息。@font-face 规则还指定如何根据设计者需要指定的字体来为文档选择
字体。
5. @charset
该规则用于定义样式单使用的字符集。指定编写样式单的字符集有 3 种方式,并且以
如下的顺序选择优先级:
(1) 网页头部标识元素 meta 中的 Content 属性参数 charset;
(2) @charset 规则;
(3) 与文档相关联的特性和属性。
@charset 规则必须出现在文档的最前,前面不能有任何其他字符。
6.5.2 新增属性
CSS2 扩充了许多新的属性,使得对于版面的设置更美观,更合理。下面对其中几个进
行简单介绍。
1. 字体属性
在 CSS2 中,对字体属性的设置主要增加了以下功能。
(1) font-size-adjust:设置或检索用于对象中文本的字体名称序列是否强制使用同一尺
寸,其取值分为 none 或数字,当取值为 none 时允许字体序列中每一字体遵守它自己的尺
寸,当取值为数字时表示为字体序列中所有字体强迫指定同一尺寸。
(2) font-stretch:设置或检索用于对象中文本的文字是否有横向的拉伸变形。
(3) text-shadow:设置或检索对象中文本的文字是否有阴影及模糊效果。
2. 文本属性
在 CSS2 中,对文本属性的设置主要增加了以下功能。
(1) direction:设置文本流的方向,表示文本流是从左到右还是从右到左的。
(2) unicode-bidi:在同一个页面里存在从不同方向读进的文本显示,主要和 direction
一起使用。
3. 其他属性
CSS2 中新增了定位属性检索对象的定位方式,具体有如下 6 种。
(1) position:检索对象的定位方式。
·135·
·136· XML 实用教程
6.5.3 其他伪类
CSS 新增了下列伪类,使得在页面设置和排版方面的功能更加丰富了。
(1) focus:设置对象在成为输入焦点(该对象的 onfocus 事件发生)时的样式表属性。
(2) first-child:设置对象(Selector1)的第一个子对象(Selector2)的样式表属性。
(3) first:设置页面容器第一页使用的样式表属性(用于@page 规则)。
(4) left:设置位于装订线左边的所有页面使用的样式表属性(用于@page 规则)。
(5) right:设置位于装订线右边的所有页面使用的样式表属性(用于@page 规则)。
(6) lang:设置对象使用特殊语言的内容样式表属性。
由于篇幅关系, 关于 CSS2 的新增功能不能一一介绍, 其他相关内容读者可参考 http://www.w
3.org/TR/REC-CSS2/。
6.6 综 合 实 例
1. 实例简介
这里使用 CSS,将存在 XML 文档中的一段文字以指定的格式显示出来。同时,为整
个页面设置了一张图片。
2. 实例实现
(1) 打开一个文本编辑器,在其中输入如例 6.5 的 XML 文档和 CSS 样式文件。
(2) 将文件分别存为 code6_5.xml 和 code6_5.css。
(3) 用 IE 打开 XML 文件,查看没有使用 CSS 的文档效果。注释命令如下:
<!--先将链接 CSS 样式表的指令语句屏蔽起来。
-->
·136·
第6章 层叠样式表 ·137·
<picture/>
<commentary> 李白(701-762),字太白。祖籍陇西成纪,隋末迁居中亚的碎叶城。
李白一生绝大部分时间是在玄宗统治的盛唐即开元、天宝年间度过的。在李白流
传下来的九百多篇诗中,大部分鲜明的表现了他对封建贵权的轻蔑,对腐朽政治
的揭露和对人民疾苦的同情,对祖国壮丽山川的赞美。同时也由于封建统治思想
的严重影响,李白的不少作品往往流露道家人生如梦、及时行乐和儒家“ 穷则
独善其身”的消极情绪。李白是我国唐代与杜甫并称的伟大诗人,他的诗歌各体
俱佳,而其中又以七言歌行与七言绝句最为擅长。李白代表作《 望庐山瀑布 》。
</commentary>
<resume>日照香炉升紫烟,
遥看瀑布挂前川。
飞流直下三千尺,
疑是银河落九天。
作者 李白
</resume>
</paper>
·137·
·138· XML 实用教程
}
syllabus{
display:"block";
font-style:italic;
font-weight:bold;
font-size:"15pt";
font-family:"楷体_gb2312";
}
picture {
background-image: url(PUBU.GIF);
background-repeat: no-repeat;
background-position: center;
float:left;
width: 240px;
height: 130px;
}
commentary{
font-size:12pt;
font-weight:bold;
font-style:italic;
text-align:right;
color:orange;
text-indent: 0.75cm;
}
图 6.5 综合实例的执行效果
3. 实例说明
本实例的主要目的是让读者熟悉 CSS 的使用方法和特点,并在与未使用样式表的 XML
文档作对比的过程中,了解 CSS 的强大功能。在实例中,综合运用了字体样式控制、字体
大小和字型控制、元素定位技术以及图片设置技术等,使得提取出来的 XML 信息重新组
织成一幅漂亮的画面。读者可以通过这个实例,对本章介绍的 CSS 的基本结构有更为形象
的认识。
·138·
第6章 层叠样式表 ·139·
6.7 小 结
6.8 习 题
·139·
第 7 章 XML 数据源对象
7.1.2 数据绑定
1. 数据绑定的作用和意义
要在 HTML 网页中使用 XML 文档中的数据,必须进行数据绑定(Data Binding)。数据
绑定就是将外部数据,如 XML 文档、数据库或使用 OLE-DB 链接的外部数据集成到 HTML
文件中,然后使表格等 HTML 元素绑定 XML 文档元素,从而实现 XML 数据在 HTML 页
面中的显示。HTML 绑定意味着和一个 HTML 元素关联的值是由一个特定来源提供的。绑
定 HTML 元素时,更新其值会造成关联结点的文本同时更新。
当 IE 打开包含 XML 数据岛的 HTML 页面时,其内置的 XML 解析器读取并分析 XML
文档,同时创建一个名为数据源对象 DSO 的 ActiveX 对象,它可以存储或缓存 XML 数据,
并提供对这些数据的访问。DSO 把 XML 数据当成记录集(recordset)存储,XML 文档包含
树状的数据库,每一个分支都有一系列类型相同的记录元素,每一个记录元素又可包含嵌
套(分支)的记录。当 XML 文档包含很多记录时,可以使用分页功能一次显示一组记录。
数据绑定体系结构包括 4 个组成部分:数据源对象(Data Source Object)、数据显示对象
(Data Consumers)和两个代理器(Binding Agent 与 Table Repetition Agent)。数据源对象向网
页提供数据,数据显示对象就是显示数据的 HTML 元素,代理器则用来保证前两者的工作
同步。
2. 使用表格时数据绑定的方法
数据控件主要负责管理数据,并为 HTML 元素提供数据,而 HTML 元素则将数据显
示在屏幕上。为了将数据源与 HTML 元素绑定,需要进行以下操作:
(1) 建立 HTML 文档。确定所要进行的信息展示或处理工作,依照程序员喜欢的界面
风格建立好一个 HTML 文档。
(2) 加入<XML>标记。在 HTML 文档中加入<XML>标记,从而在 HTML 中嵌入 XML
格式的数据,或者引用外部的 XML 格式的文件。设置<XML>标记的 id 属性,可以通过脚
本访问这些数据,也可以把它与<table>捆绑到一起。还可以设置<XML>的 src 属性,导入
外部的 XML 格式数据。
(3) 建立表格。根据所要展示的字段个数,设置表格的表头和表体,表体中建立一
个空白行。
(4) 定义数据源 datasrc。在表格标记<table>中加入 datasrc 属性,并赋值为数据源的
名称,这样表格就成为包含数据的数据控件。注意,在数据源名称前必须要加“#”。
(5) 确定被绑定的字段 datafld。在表格要显示数据的各列标记<td>中加入<span>、<div>
·141·
·142· XML 实用教程
·142·
第7章 XML 数据源对象 ·143·
<quantity>30</quantity>
<item_status>pending</item_status>
</item>
<item>
<bookID>003</bookID>
<quantity>20</quantity>
<item_status>pending</item_status>
</item>
</items>
</order>
</orders>
·143·
·144· XML 实用教程
图 7.2 显示单条记录的结果
1. 数据可以在本地处理
XML 分析器可以在读取数据后,将它递交给本地应用程序(例如浏览器)进一步查看或
处理。数据也可以由使用 XML 对象模型的脚本或其他编程语言来做各种处理。
2. 提供给客户端结构化数据视图
传递到客户端的数据形成本地数据集,可以用多种方式表示。如程序员可以根据需要
和配置等因素,以视图的形式动态地表现给浏览器。
3. 集成不同来源的结构化数据
在服务器端可以集成来自不同后台数据库和其他多种应用程序的数据,使该数据以
XML DSO 的方式传递给客户端或者其他服务器,做进一步聚合、处理和分布。由于 XML
是可扩展和自描述的,所以它可以用于描述来自不同数据库或应用程序的数据,不需要数
据的内置描述,也能够接收和处理数据。
4. 通过粒度更新来提高性能
XML 允许粒度更新,开发人员不必在每次有改动时都发送整个结构化数据集。当数据
更新时,只需要刷新中间显示数据的部分,而页面的其他部分不变,就好像没有刷新一样,
显示效果更好。因为只下载了数据部分,网页的其他部分没有重复下载,浏览速度更快。
如果灵活应用,还可以实现无刷新搜索和分页等功能。
5. 网页界面修改不易破坏数据
网页制作者可以灵活地改变页面风格而无须担心破坏数据显示代码,因为数据和页面
是分离的,相关代码也很少。
·144·
第7章 XML 数据源对象 ·145·
HTML 元素 可 更 新 呈现 HTML
a 否 否
applet 是 否
button 否 是
div 否 是
frame 否 否
iframe 否 否
img 否 否
input type=“button” 否 是
input type=“checkbox” 是 否
input type=“hidden” 是 否
input type=“password” 是 否
input type=“radio” 是 否
input type=“text” 是 否
legend 否 是
marquee 否 是
select 是 否
span 否 是
table 否 是
textarea 否 否
·145·
·146· XML 实用教程
·146·
第7章 XML 数据源对象 ·147·
·147·
·148· XML 实用教程
<tr>
<td><span DATAFLD="customerID"></span></td>
<td><span DATAFLD="order_date"></span></td>
<td><span DATAFLD="order_status"></span></td>
<td>
<table datasrc="#XMLdata" datafld="items">
<tr><td><div datafld="$text"></div></td></tr>
</table>
</td>
</tr>
</table>
</BODY>
</HTML>
·148·
第7章 XML 数据源对象 ·149·
<tr><td>
<table border="1" datasrc="#XMLdata" datafld="item">
<thead>
<th>bookID</th>
<th>quantity</th>
<th>item_status</th>
</thead>
<tr>
<td><span datafld="bookID"></span></td>
<td><span datafld="quantity"></span></td>
<td><span datafld="item_status"></span></td>
</tr>
</table>
</td></tr>
</table>
</td>
</tr>
</table>
</BODY>
</HTML>
上例代码中采用 3 层嵌套的表格实现数据的显示。外层表格(第一层)和各级内嵌表格
的 数 据 源 都 定 义 为 datasrc=“#XMLdata” , 内 嵌 的 第 二 层 表 格 的 具 体 数 据 定 义 为
datafld=“items”,再往里嵌套的第三层表格数据指定为 datafld=“item”,这样 item 的次级元
素的值就能对应到具体的单元格了。对于多元素的单元格,应当在 td 元素内部嵌套一个
表格。
·149·
·150· XML 实用教程
·150·
第7章 XML 数据源对象 ·151·
·151·
·152· XML 实用教程
<title>20 世纪欧美文学简史</title>
<author>李明滨</author>
<publisher>北京大学出版社</publisher>
<ISBN>7-301-04616-2</ISBN>
<price>21.8</price>
</book>
<book id="0098" bookcategory="文学" amount="140" remain="76"
discount="7.0">
<title>西方文艺理论名著教程(上)</title>
<author>胡经之</author>
<publisher>北京大学出版社</publisher>
<ISBN>7-301-00649-7</ISBN>
<price>24</price>
</book>
<book id="0012" bookcategory="文学" amount="210" remain="60"
discount="8.5">
<title>西方文艺理论名著教程(下)</title>
<author>胡经之</author>
<publisher>北京大学出版社</publisher>
<ISBN>7-301-00179-7</ISBN>
<price>23</price>
</book>
<book id="0036" bookcategory="文学" amount="100" remain="80"
discount="8.3">
<title>中国文学理论批评史教程</title>
<author>张少康</author>
<publisher>北京大学出版社</publisher>
<ISBN>7-301-04091-1</ISBN>
<price>25</price>
</book>
<book id="0018" bookcategory="计算机" amount="200" remain="100"
discount="8.2">
<title>计算机导论</title>
<author>丁跃潮等</author>
<publisher>高等教育出版社</publisher>
<ISBN>7-04-014768-8</ISBN>
<price>19.7</price>
</book>
<book id="0218" bookcategory="计算机" amount="400" remain="300"
discount="8.5">
<title>程序设计基础</title>
<author>张杰敏主编</author>
<publisher>高等教育出版社</publisher>
<ISBN>7-04-012652-4</ISBN>
<price>17.6</price>
</book>
<book id="0318" bookcategory="计算机" amount="100" remain="60"
discount="8.0">
<title>数据结构与算法</title>
<author>王晓东编</author>
<publisher>高等教育出版社</publisher>
<ISBN>7-04-013204-4</ISBN>
·152·
第7章 XML 数据源对象 ·153·
<price>21.8</price>
</book>
<book id="0181" bookcategory="计算机" amount="250" remain="156"
discount="8.0">
<title>XML Web Service 开发</title>
<author>微软公司著</author>
<publisher>高等教育出版社</publisher>
<ISBN>7-04-015825-6</ISBN>
<price>65.00</price>
</book>
<book id="0189" bookcategory="计算机" amount="230" remain="160"
discount="8.0">
<title>VB.NET 程序设计语言</title>
<author>微软公司著</author>
<publisher>高等教育出版社</publisher>
<ISBN>7-04-013188-9</ISBN>
<price>86.00</price>
</book>
<book id="0028" bookcategory="计算机" amount="100" remain="90"
discount="7.5">
<title>JavaScript 速成教程</title>
<author>Michael Moncur 著</author>
<publisher>机械工业出版社</publisher>
<ISBN>7-111-09070-5</ISBN>
<price>28.00</price>
</book>
<book id="0074" bookcategory="计算机" amount="130" remain="78"
discount="7.8">
<title>软件工程 Java 语言实现</title>
<author>Stephen R.Schach</author>
<publisher>机械工业出版社</publisher>
<ISBN>7-111-06714-2</ISBN>
<price>51.00</price>
</book>
<book id="0109" bookcategory="计算机" amount="210" remain="160"
discount="8.0">
<title>人工智能</title>
<author>Nils J. Nilsson</author>
<publisher>机械工业出版社</publisher>
<ISBN>7-111-04738-6</ISBN>
<price>45.00</price>
</book>
<book id="0305" bookcategory="计算机" amount="115" remain="26"
discount="7.5">
<title>ASP 开发实例</title>
<author>清汉计算机工作室</author>
<publisher>机械工业出版社</publisher>
<ISBN>7-980039-74-2</ISBN>
<price>53.00</price>
</book>
</books>
·153·
·154· XML 实用教程
·154·
第7章 XML 数据源对象 ·155·
<OBJECT classid="clsid:550dda30-0541-11d2-9ca9-0060b0ec3d39"
id="XMLDSO">
</OBJECT>
<HTML>
<HEAD><title>使用表格绑定 XML</title></HEAD>
<script language="JavaScript">
function loadXML()
{ // 加载 XML 文件
var XMLdoc = XMLDSO.XMLDocument;
XMLdoc.load("code7_6.XML");
}
</script>
<BODY onload="loadXML()">
<h2 align="center"><font size="4">使用<OBJECT>标记建立 DSO 对象
</font></h2>
<table datasrc="#XMLDSO" border="1" align="center">
<thead>
<th>书名</th><th>类别</th><th>书号</th><th>作者</th>
<th>出版社</th><th>定价</th><th>剩余量</th>
</thead>
<tr>
<td><span datafld="title"></span></td>
<td><span datafld="bookcategory"></span></td>
<td><span datafld="ISBN"></span></td>
<td><span datafld="author"></span></td>
<td><span datafld="publisher"></span></td>
<td><span datafld="price"></span></td>
<td><span datafld="remain"></span></td>
</tr>
</table>
</BODY>
</HTML>
·155·
·156· XML 实用教程
表 7-2 控制表格每页显示记录条数的方法
方 法 说 明
nextPage 下一页
previousPage 上一页
firstPage 第一页
lastPage 最后一页
·156·
第7章 XML 数据源对象 ·157·
</table><hr>
<center>
<input type="button" onclick="tblbooks.previousPage()" value="上一页">
<input type="button" onclick="tblbooks.nextPage()" value="下一页">
每一页<input type=text value="3" size="5"
onblur="tblbooks.dataPageSize=this.value;">笔
</center>
</BODY>
</HTML>
7.5 综合应用实例
·157·
·158· XML 实用教程
ISBN.innerHTML = objbook("ISBN").value;
author.innerHTML = objbook("author").value;
publisher.innerHTML = objbook("publisher").value;
price.innerHTML = objbook("price").value;
remain.innerHTML = objbook("remain").value;
}
function pre_page()
{
if (pageno>1)
{ tblbooks.previousPage();
pageno=pageno-1; }
}
function next_page()
{
if (pageno<objbook.RecordCount/tblbooks.dataPageSize)
{ tblbooks.nextPage();
pageno=pageno+1; }
}
</script>
<BODY>
<center><b>分页显示书本信息</b></center>
<table ID=tblbooks datasrc="#XMLDSO" border="1" align="center"
datapagesize=3 >
<thead>
<th>书名</th><th>类别</th><th>书号</th><th>作者</th><th>出版社
</th><th>定价</th><th>剩余量</th>
</thead>
<tr>
<td onclick=SelectRecord(this)><span datafld="title"></span></td>
<td onclick=SelectRecord(this)><span datafld="bookcategory"></span></td>
<td onclick=SelectRecord(this)><span datafld="ISBN"></span></td>
<td onclick=SelectRecord(this)><span datafld="author"></span></td>
<td onclick=SelectRecord(this)><span datafld="publisher"></span></td>
<td onclick=SelectRecord(this)><span datafld="price"></span></td>
<td onclick=SelectRecord(this)><span datafld="remain"></span></td>
</tr>
</table>
<hr>
<center>
<input type="button" onclick="pre_page()" value="上一页">
<input type="button" onclick="next_page()" value="下一页">
每一页<input type=text value="3" size="5"
onblur="tblbooks.dataPageSize=this.value;">笔
</center>
<center>请单击上表有兴趣的图书行</center>
<hr>
<center>单本图书信息:书名: <span id="title"></span></center>
<table border="1" align="center" >
·158·
第7章 XML 数据源对象 ·159·
<tr><td width="50%">
分类: <span id="bookcategory"></span><br>
书号: <span id="ISBN"></span><br>
作者: <span id="author"></span><br>
</td>
<td width="50%">
出版: <span id="publisher"></span><br>
定价: <span id="price"></span> 元<br>
剩余: <span id="remain"></span>本<br>
</td>
</tr>
</table>
<hr>
</BODY>
</HTML>
7.6 小 结
·159·
·160· XML 实用教程
7.7 习 题
1. 什么是数据岛?
2. 数据源对象的用途是什么?
3. XML 文档是数据库吗?试比较 XML 文档和数据库的特点、架构。
4. 试述数据绑定的作用和意义。
5. 试述使用表格时数据绑定的步骤。
6. XML 与 HTML 结合的优势有哪些?
7. 将 HTML 元素和 XML 文档绑定时要注意哪些问题?
8. 试用 HTML 的<a>标记绑定 XML 文档中的网址,编辑能够出现超文本链接的网页。
9. 在本书中找两个例子,使用 HTML 的<div>标记替换原来的<span>标记绑定 XML
文档。
10. 试用 3 种方法加载 XML 文档,分别写出代码。
11. 编写含有脚本的 HTML 代码,使用户能够翻阅前后条记录。
12. 编写含有脚本的 HTML 代码,使用户能够翻页查看记录。
13. 编写代码,使之能够查阅全班同学的通讯录。
·160·
第 8 章 XSL 转换
教学提示:XSL 的目的就是为生成 XML 文档提供一个功能强大而又容易使用的样式
语法。实际上 XSL 分为 XSL 转换(XSL Transformation,XSLT)和格式化对象
(Formatting Object,FO)。XSLT 是一种专门用来转换 XML 文档的语言。它将一个
XML 文档(输入或源文档)转换为另一篇 XML 文档(输出或结果文档)。XSLT 只是一
种转换机制,FO 用来描述如何对文档进行格式化。本章主要介绍 XSLT 的基础知识,
XSLT 中使用到的 XML 元素,模板等概念,以及综合运用 XSLT 将 XML 转换成 HTML
的实例。
教学目标:理解 XSL 的一些基本概念,弄清 XSL 的结构。了解 XPath 在 XSLT 中所
起的作用。掌握 XSLT 转换语言的基础知识,熟悉 XSLT 所使用的元素、模板、函
数等,通过具体实例,学会综合运用 XSLT 编写转换模板。
8.1 XSL 概述
可扩展的样式表语言(eXtensible Stylesheet Language,XSL)最早由 W3C(World
Wide Web Consortium)于 1999 年提出。它定义了如何转换和表示 XML 文档。比
CSS 功能要强大得多。XSL 能够向输出文件里添加新的元素或者移动元素,也
能够重新排列或者索引数据,它可以检测并决定哪些元素被显示,显示多少等。
它使用 XPath 匹配结点。把一个 XML 文档转换为另一个不同的文档。得到的文
档可以是 XML、HTML、无格式文本或任何其他基于文本的文档。XSL 的第二
部分是 XSL 格式化对象。格式化对象提供了另一种方式,来格式化显示 XML
文档,以及把样式应用到 XML 文档中。
8.1.1 XSL 的意义
XML 是一种计算机程序间交换原始数据的简单而标准的方法。它的成功并
不在于它容易被人们书写和阅读,更重要的是,它从根本上解决了应用系
统间的信息交换。因为 XML 满足了以下两个基本的需求。
(1) 将数据和表示形式分离。就像天气预报的信息可以显示在电视、手持式
移动电话机或者其他不同设备上一样,XML 的显示或表现形式可以是多样
的。
(2) 在不同的应用之间传输数据。电子商务数据交换的与日俱增使得这种需
求越来越紧迫。
为了使数据便于人们的阅读和理解,需要将信息显示或者打印出来,例如
将数据变成一个 HTML 文件,一个 PDF 文件,甚至是一段声音。同样,为
了使数据适合不同的应用程序,必须能够将一种数据格式转换为另一种数
据格式,比如需求格式可能是一个文本文件、一个 SQL 语句、一个 HTTP
信息、一定顺序的数据调用等。而 XSLT 就是用来实现这种转换功能的语
言。将 XML 转换为 HTML,是目前 XSLT 最主要的功能。
8.1.2 XSLT 和 CSS 的比较
CSS 同样可以格式化 XML 文档,那么有了 CSS 为什么还需要 XSLT 呢?
因为 CSS 虽然能够很好地控制输出的样式,比如色彩、字体、大小等,但
是它有严重的局限性,就是:
(1) CSS 不能重新排序文档中的元素;
(2) CSS 不能判断和控制哪个元素被显示,哪个不被显示;
·162· XML 实用教程
适用在 XHTML 可以 可以
·162·
第8章 XSL 转换 ·163·
·163·
·164· XML 实用教程
·164·
第8章 XSL 转换 ·165·
一般来说,XPath 中路径开始于当前上下文,但在文件系统中,路径可
以采用绝对定位而非相对定位的方式。XPath 中也可以有这种方式,使
用开始斜线“/”指向文档的根而不是文档的第一个结点,如“/book/title”
能返回顶级 book 结点内的 title 结点。
双斜线“//”是结点的通配路径。在有的例子中,<xsl:template
match=“//title”>会返回文档内各个位置的<title>结点而不论其是否在
“/book/title”还是位于“/book/chapter/title”。双斜线还可以位于路径
的中间,如“/book//title”则返回 book 结点下所有的<title>结点。
在路径的末尾加一个星号“*”会返回所有当前路径下所有的结点,这
与文件系统通配符的用法是完全一样的。在上面的例子中,
“/book/chapter/*”会同时检索出<book>根结点下的<chapter>结点下的
所有结点,而路径“//*”则会返回文档中的所有结点。
2. 访问数据
XPath 还提供了根据比较方法选择特定属性或结点值的语法。
“@”指结点的标记属性。假设 chapter 有 type 属性,按“@type”的
方式就可访问。如果为了可以从文档的任何地方访问它,访问路径应
该写成“/book/chapter/@type”。
方括号从一个集合中选出一个结点,很像是传统编程中的数组。为了
只选出第二个 chapter,可以用一个形如“/book/chapter[2]”的 XPath
表达式。注意,集合中的第一个结点的编号是 1,而不是大多数编程语
言中规定的 0。
同时,也可以把这些条件组合起来按照其属性值选择结点,在条件为
真时才返回结点。条件包含在方括号中,跟在要应用条件的元素之后,
如:
<xsl:template match="price[@unit='USD']">
<price>
<unit>USD</unit>
<amount>100</amount>
</price>
<price>
<unit>RMB</unit>
<amount>300</amount>
</price>
那么“price[@unit='USD']”条件匹配的内容就是:
<price>
<unit>USD</unit>
<amount>100</amount>
</price>
·165·
·166· XML 实用教程
结点选择功能还有许多,其内容已经超出了本文所涉及的范围,
有兴趣的读者可以查阅相关资料。
3. 高级方法
除了导航和数据提取之外,XPath 还提供了字符计数、变量设置、基本
数学计算、找出最近元素以及其他多种类型的模式匹配等函数。例如,
如果在转换时,只关心当前结点名称为 contactInfo 的结点,显出顾客
联系信息,那么可以这样使用:
[.!nodeName()='contactInfo']
·166·
第8章 XSL 转换 ·167·
·167·
·168· XML 实用教程
·168·
第8章 XSL 转换 ·169·
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
·169·
·170· XML 实用教程
然后,在示例的代码中看到有如下的代码。
<xsl:template match="/">
…
</xsl:template>
<xsl:template match="书籍">
<table Border="1">
<xsl:for-each select="书名" >
…
</xsl:for-each>
</table>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="书籍" />
</xsl:template>
<xsl:template match="书籍">
…
</xsl:template>
·170·
第8章 XSL 转换 ·171·
其中,“+”表示按降序排列,“-”表示按升序排列,order-by 是 XSL
语法中的关键字。
如果只想在列表中取出某几行该怎么操作呢?假设只想取出书名为“三国
演义”的行,见下面的代码:
<xsl:template match="书籍">
<table Border="1">
<xsl:for-each select="书名" order-by="+书名">
<xsl:if test=".[书名='三国演义']">
<tr>
<td><xsl:value-of select="书名"/></td>
<td><xsl:value-of select="价格"/></td>
</tr>
</xsl:if>
</xsl:for-each>
</table>
</xsl:template>
这里有一个新的句法为</xsl:if test="[书名='三国演义']">,它表示如果".[书
名='三国演义']"为 true,就执行该段里面的语句,如果为 false 就不执行。它
和 C++中的 if 语句的概念基本一样。
前面用<xsl:value-of select="元素名称"/>取出的都是一个元素的值,但是要
取出元素某一个属性的值该怎么做呢?可以采用下面的格式:
<xsl:value-of select="元素名称/@属性名称"/>
<罗贯中 网址="www.lai.org">罗贯中的生平介绍</罗贯中>
·171·
·172· XML 实用教程
<itemName>红楼梦</itemName>
<price>120.00</price>
<publisher>文艺出版社</publisher>
</item>
</shoppingCart>
·172·
第8章 XSL 转换 ·173·
·173·
·174· XML 实用教程
<table>
<tr>
<td>Hello world!</td>
<td><img src="earth.gif"/></td>
</tr>
</table>
在以上的代码段中,每个结点都有自己的开、闭标记,两个标记之间是更
多的结点和文本字符串。img 结点有一个 src 属性而没有内容,紧挨着开标
记的是一个终止斜线。这个终止斜线和文本都在 td 结点内嵌套,而后者又
在 tr 结点内嵌套,显然 tr 结点则在 table 内嵌套。
XSLT 文档通常被分解为离散的模板,每个模板负责处理 XML 文档内某一
类型的标记。在这些模板内,XSLT 要用到标量、传递参数、循环条件以及
其他转换 XML 的元素。
xsl:stylesheet 标记是任何 XSLT 风格表单的最外层标记,并要为文档指定版
本和一个或者多个命名空间,例如:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform>
...
</xsl:stylesheet>
·174·
第8章 XSL 转换 ·175·
给定结点的一个模板。
8.4 XSLT 模板体
使用 XPath 从 XML 文档中提取出要进行操作的结点集,接着需要使用 XSL 定
义的元素来转换这些结点。前面的例子已经显示了使用这些元素转换 XML 文
档。这些元素提供了类似于编程语言的功能。这些 XSL 元素见表 8-4。
表 8-4 XSL 元素列表
XSL 元素 含 义
xsl:value-of 插入被选择结点的值至输出文档
xsl:copy 复制指定结点下的内容到输出文档
xsl:comment 在输出中创建一个注释结点
xsl:when 在一个 xsl:choose 元素内提供单一的条件判断
xsl:if 简单的条件判断
xsl:template 为输出定义一个处理规则
这些都是在模板中要使用到的元素。下面具体介绍几个 XSLT 元
素。
8.4.1 索引与过滤
在介绍转换元素之前,先来看一下 order-by 和 select 属性。在上面的例子中
已经使用过 xsl:for-each 元素以及这两个属性了。
order-by 属性用于将元素的显示按一定的顺序排列,该属性带有一个“+”
或者“-”的符号,用来定义索引的方式,是升序还是降序排列。符号后
面的名字就是要索引的关键字,例如:
<xsl:for-each select="shoppingCart/item[itemName='三国演义']">
·175·
·176· XML 实用教程
对某一结点下的内容进行循环输出,一般可用如下方式表示:
·176·
第8章 XSL 转换 ·177·
<xsl:value-of select="name">
例如,上例中要求取出顾客的全部信息,则可以改写模板文件。
<xsl:template match="/">
<xsl:for-each select="contactInfo/customer">
<div><xsl:value-of select="name"/></div>
<div><xsl:value-of select="email"/></div>
<div><xsl:value-of select="address"/></div>
<div><xsl:value-of select="zipcode"/></div>
</xsl:for-each >
</xsl:template>
执行后,这些结点的值会被显示出来,xsl:value-of 语法说明需要输出一个
结点的值,而 select=“name”则定义需要被输出的元素为 name。整个过程与
数据库中查询数据类似。当然,xsl:value-of 查询方式还有更多,更复杂的
语法,因为是涉及寻找和定位的功能,与 XPath 语法密切相关。有兴趣可
以查阅相关的 Xpath 语法,这里不再介绍。
8.4.4 xsl:choose、xsl:when 和 xsl:otherwise
这 3 个元素组成了程序设计语言中的 switch 语句。xsl:choose 元素类似于
switch 语句的执行多条件判断。而 xsl:when 则是每一个判别,其 test 属性值
就是一个条件表示式。正如 switch 语句中的 default 分支,当所有条件都不
满足时,则执行的是 xsl:otherwise 元素;当条件满足时,元素的内容被得到
应用。一般形式:
·177·
·178· XML 实用教程
< xsl:choose>
<xsl:when test="pattern">
<!--样式定义-- >
</xsl:when>
<xsl:otherwise>
<!--样式定义-- >
</xsl:otherwise>
</xsl:choose>
<xsl:template match="/">
<xsl:for-each select="contactInfo/*">
<xsl:choose>
<xsl:when test=".[.!nodename()=’customer] ">
<div
style="background-color:teal;font-size:12pt"><xsl:value-of
select="name"/></div>
</xsl:when>
<xsl:otherwise>
<div style="font-size:12pt">您所订购的图书:</div>
<!-- 关于图书的各子结点样式定义 -->
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
这里的测试条件“.[.!nodeName()=’customer]”意为满足当前结点名为
customer 的所有结点。方法 nodeName()用来取得结点的名称。
8.4.5 xsl:if、xsl:element 和 xsl:attribute
xsl:if 是类似常规程序语言的 if 条件语句,允许设定结点满足某个条件时,
被模板处理。它没有 else 属性,要实现多分支只能用上面所介绍的
xsl:choose。xsl:element 是在输出文档中创建一个元素,而 xsl:atrribute 则是
创建一个属性。
例如当遇到顾客的地址时,需要改变字体大小,并且用粗体显示。可以这
样编写 XSL 文件。
<div>
<xsl:if test=".[.!nodeName()=’address’] ">
<xsl:attribute name="style">font-weight:bold</xsl:attribute>
</xsl:if>
</div>
·178·
第8章 XSL 转换 ·179·
<hyperlink>
<name>X_Agent</name>
<logo>gw.jpg</logo>
<homepage>http://www.csdn.net</homepage>
</hyperlink >
<div class="b">
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:value-of select="hyperlink/homepage"/>
</xsl:attribute>
<xsl:element name="img">
<xsl:attribute name="src">
<xsl:value-of select="hyperlink/logo"/>
</xsl:attribute>
</xsl:element>
</xsl:element>
</div>
8.4.6 变量
XSL 还可以利用变量处理信息。可以为变量赋值的元素有 xsl:variable 和
xsl:param。一般 xsl:variable 使用格式:
<xsl:variable name="sum"
select="sum(shoppingcart/shoppingItem/item)"/>
·179·
·180· XML 实用教程
</xsl:apply-templates>
在结点匹配某个模板的情况下,XSLT 通常假定这个模板会专注该结点的所
有内容而不去处理它们。模板内的 xsl:apply-templates 元素则告诉 XSLT 处
理器依次处理子结点内容。xsl:apply-templates 元素的使用可以实现模板的
递归调用。
xsl:apply-templates 默认地处理所有最近的子结点。select 属性可以指定特定
的派生结点进行处理。
那么 XSL 解析器如何知道从哪里开始执行模板呢?对于单模板样式文件,这
不成问题。然而,对于多模板样式文件,必须给处理程序一个提示,
xsl:apply-templates 用来执行哪一个结点被模板具体处理。可以将它理解为
程序中调用子函数。多模板样式表包含一个告知 XSL 解析器从哪里开始的
默认模板。首先执行默认模板,接下来依次处理每一个模板。XSL 寻找应
用于文档根元素的默认模板,例如:
<xsl:template match="/">
<p><xsl:apply-templates /></p>
</xsl:template>
斜杠“/”代表文档的根。XSL 处理程序从这里开始,并且按照模板体的指
令向下继续执行。对于 xsl:apply-templates 元素来说,还有 select 属性用来
定义确切的结点名称。xsl:apply-templates 总是包含在 xsl:template 元素中的。
<xsl:template match="/">
<xsl:apply-templates select="contactInfo"/>
</xsl:template>
这段代码说明模板匹配整个文档(根结点),具体执行时处理根结点下所有的
contactInfo 元素。
<xsl:template match="contactInfo">
<p><xsl:apply-templates/></p>
</xsl:template>
<xsl:template match="/book">
This book is entitled "<xsl:value-of select="title"/>"
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="/book/chapter">
This is chapter <xsl:number/>, entitled " <xsl:value-of
select="title"/>"
</xsl:template>
可以看到多个模板把控制权按照一定的指令链转交给了其他模板。这样做
把 XSLT 文档分解成可读的多个部分,使得模板的重用成为可能。
·180·
第8章 XSL 转换 ·181·
模板调用还有另一种方式就是:xsl:call-template。xsl:call-template 元素按照
名字执行其他模板,它的语法格式:
<xsl:call-template name="name">
</xsl:call-template>
<xsl:template match="/book/chapter">
<xsl:call-template name="output-chapter-info"/>
</xsl:template>
<xsl:template name="output-chapter-info">
The name of chapter <xsl:number/> is "<xsl:value-of
select="title"/>".
</xsl:template>
·181·
·182· XML 实用教程
在上面的例子中,一共设计有 4 个模板。
(1) 根结点模板:<xsl:template match="/">。
(2) cart 结点模板:<xsl:template match="shoppingcart">。
·182·
第8章 XSL 转换 ·183·
<xsl:template match="/">
<html>
<head>
<title>书籍订单——E-shop</title>
<style> .title{font-size:15pt; font-weight:bold;
color:blue } .name {color:red} </style>
</head>
<xsl:apply-templates/>
</html>
</xsl:template>
<xsl:template match="shoppingcart">
<body>
<xsl:apply-templates/>
</body>
</xsl:template>
<xsl:template match="shoppingcart/customer">
<div style="background-color:teal;
font-weight:bold;"><xsl:value-of select="name"/> </div>
<div><xsl:value-of select="email"/></div>
<div ><xsl:value-of select="address"/></div>
<div ><xsl:value-of select="zipcode"/></div>
</xsl:template>
由此在输出文档中,生成顾客的联系信息。这个模板里不包含
apply-templates,因为已经处理了 customer 的所有子结点,无须再向下遍历。
解析器处理完 customer 结点后,退回到它的上级结点 shoppingcart,然后再
查找 shoppingcart 结点的其他子结点,发现 shoppingItem 结点及相匹配的模
板:
<xsl:template match="shoppingcart/shoppingItem">
·183·
·184· XML 实用教程
<table border="1">
<thead>
<td><B>编 号</B></td>
<td><B>书 名</B></td>
<td><B>价 格</B></td>
<td><B>出 版 社</B></td>
</thead>
<xsl:for-each select="./item" order-by="itemNo">
<tr>
<td><b><xsl:value-of select="itemNo"/></b></td>
<td><xsl:value-of select="itemName"/></td>
<td><xsl:value-of select="price"/></td>
<td><xsl:value-of select="publisher"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
这个模板在输出文档中列出顾客订购的书籍清单。至此,完成整个 XML 文
档的转换。可以看出,apply-templates 是对样式表的递归调用,类似于对树
进行优先搜索。上例转换出来的效果如图 8.4 所示。
·184·
第8章 XSL 转换 ·185·
·185·
·186· XML 实用教程
·186·
第8章 XSL 转换 ·187·
<study_year>2</study_year>
</info>
<info name="ChenKai">
<number>A1003</number>
<address>XingJiang</address>
<study_year>2</study_year>
</info>
</student>
·187·
·188· XML 实用教程
图 8.7 结果图
·188·
第 9 章 XML 文档对象模型
利用 DOM,程序开发人员可以动态地创建文档,遍历文档结构,添加、修改、删除文
档内容,改变文档的显示方式等。
修改、添加、删除、创建树中的结点和内容。
将第 1 章如图 1.4 所示的 XML 层次模型实例补全 book 结点的 5 个属性成为如图 9.1
所示 DOM 树状结构实例,这就是文档 code1_2.xml 的 DOM 结构树,只是内用有些变动。
图中矩形框表示结点,椭圆形框表示属性。显然,这棵结点树是可以依照规律遍历或访问
的。
·190·
第9章 XML 文档对象模型 ·191·
属 性 描 述 范 例
该结点的所有非属性的子结点的 AttributeNode=Element.attributes.getName
attributes
NamedNodeMap 集合 dItem (“amount”);
该结点的所有非属性的子结点的 NodeList
childNodes FirstNode =Element.childNodes(0);
集合
该结点的数据类型(只适用于某些类型
dataType AttributeType =Attribute.dataType;
Attribute 结点)
firstChild 该结点的第一个非属性的子结点 FirstChildNode =Element.firstChild;
lastChild 该结点的最后一个非属性的子结点 LastChildNode =Element.lastChild;
nextSibling 与本结点位于同一层级的后继前一结点 NextElement =Element.nextSibling;
nodeName 结点的名称 ElementName =Element.nodeName;
nodeType 表示该结点类型的数值码 NodeTypeCode =Node.nodeType;
包含该结点类型的字符串,以小写字母撰写
nodeTypeString NodeTypeString=Node.nodeTypeString;
(例如,element 或 attribute)
·191·
·192· XML 实用教程
续表
属 性 描 述 范 例
nodeValue 该结点的值(如果不含值则为 null) AttributeValue =Attribute.nodeValue;
ownerDocument 包含本结点的文档的根 document 结点 Document =Node.ownerDocument;
parentNode 该结点的父结点(并不适用于 attribute 结点) ParentElement =Element.parentNode;
previousSibling 与本结点位于同一层级的先前结点 PreviousElement =Element.previousSibling;
text 该结点与其后裔结点的全部文字内容 AllCharacterData =Element.text;
xml 该结点与其后裔结点的全部 XML 内容 XMLContent =Element.xml;
除了共同的属性和方法外,每种类型的结点都提供了附加的属性和方法,来处理该结
点类型所代表的特殊 XML 组件。例如,文档结点(document)提供了 parseError 属性,内含
任何处理文档时所产生错误的相关信息。只有文档结点拥有这种属性。
如果某个属性不适用于特定结点,则该属性将包含 null 值。例如,如果某结点代表一
个不包含任何属性的 XML 文档(如 document 或 commentNode)时,其 attributes 属性将被设
为 null。如果某结点代表某个不含有任何数据类型(只有某些属性拥有数据类型)的 XML 组
件时,该结点的 dataType 属性将被设为 null。如果结点并没有任何非属性的子结点,其
firstChild 属性将被设为 null。而如果结点为不含值的类型(如 document 或 elementNode),其
nodeValue 属性将被设为 null。
表 9-2 中每个结点拥有一组属性,可以浏览结点的层次架构,来从目前结点存取其他
结点的资料。例如,在表 9-1 中的文档,如变量 document 包含了文档的 document 根结点,
后续的程序代码将会显示最接近文档起始部分批注的内容,而 DOM 会将批注内容存储在
document 结点的第二个子结点中。
9.1.3 创建 document 对象
对于 VBScript:
set xmlDom = CreateObject("MSXML2.DOMDocument.4.0")
对于 VB:
Dim xmlDom As ObjectSet
xmlDom = CreateObject("MSXML2.DOMDocument.4.0")
或者
Dim xmlDom As DOMDocument
Set xmlDom = New DOMDocument
·192·
第9章 XML 文档对象模型 ·193·
对于 ASP(VBScript):
set xmlDom = Server.CreateObject("MSXML2.DOMDocument.4.0")
载入的文件可以视为一个树状结构的结点,其具有的属性见表 9-3。
DOM 对象 说 明
document 树状结构的根结点
node 结点对象,新增、删除和修改结点对象
nodelist 结点列表对象,就是制定结点子结点的整个树状结构
element XML 元素对象,也就是元素结点
text XML 元素内容对象,也就是内容结点
parseerror 解析器错误处理对象,如有错误,返回加载时的错误信息
在 document 对象创建之后,就得到了对文档进行操作的入口,这个文档对象可以与实
际的 XML 文档关联在一起。在 W3C 的 DOM 接口规范中,没有任何一个地方定义了 DOM
中的接口对象同实际文档相关联的方法。因此,不同的 XML 分析器所提供的加载 XML 文
档的方法也不尽相同。在 Microsoft 公司的 MSXML 解析器中,提供了一个 load 方法来加
载 XML 文档,建立 DOM 树同 XML 文档之间的关联。
以图书信息表的 XML 文档 code9_1.xml 为例,VBScript 可通过下述方式来加载文档:
Dim xmlDom
' 建立 XML DOM 对象
Set xmlDom = CreateObject("MSXML2.DOMDocument.4.0")
' 设置 xmlDom 的 async 为 false,即异步为假,保证 XML 解析器暂停执行,直到 XML 文件加
载完成
xmlDom.async = false
' 加载 XML 文件
xmlDom.load("code9_1.xml")
·193·
·194· XML 实用教程
// 建立 XML DOM 对象
var xmlDom = new ActiveXObject("MSXML2.DOMDocument.4.0")
xmlDom.async = "false"
// 加载 XML 文件的字符串
xmlDom.load("code9_1.xml")
·194·
第9章 XML 文档对象模型 ·195·
</book>
<book id="0003" bookcategory="文艺" amount="200" remain="175"
discount="8.5">
<title>西游记(上下册)</title>
<author>吴承恩</author>
<publisher>人民文学出版社</publisher>
<ISBN>7020008739</ISBN>
<price>40.12</price>
</book>
<book id="0004" bookcategory="文艺" amount="300" remain="192"
discount="8.7">
<title>水浒传(上下册)</title>
<author>吴承恩</author>
<publisher>时代文艺出版社</publisher>
<ISBN>7538714014</ISBN>
<price>40.85</price>
</book>
<book id="0065" bookcategory="文学" amount="120" remain="86"
discount="8.0">
<title>外国文学史(亚非卷)</title>
<author>朱维之</author>
<publisher>南开大学出版社</publisher>
<ISBN>7-310-01122-8</ISBN>
<price>20</price>
</book>
<book id="0076" bookcategory="文学" amount="130" remain="84"
discount="8.0">
<title>二十世纪欧美文学简史</title>
<author>李明滨</author>
<publisher>北京大学出版社</publisher>
<ISBN>7-301-04616-2</ISBN>
<price>21.8</price>
</book>
<book id="0098" bookcategory="文学" amount="140" remain="76"
discount="7.0">
<title>西方文艺理论名著教程(上)</title>
<author>胡经之</author>
<publisher>北京大学出版社</publisher>
<ISBN>7-301-00649-7</ISBN>
<price>24</price>
</book>
<book id="0012" bookcategory="文学" amount="210" remain="60"
discount="8.5">
<title>西方文艺理论名著教程(下)</title>
<author>胡经之</author>
<publisher>北京大学出版社</publisher>
<ISBN>7-301-00179-7</ISBN>
<price>23</price>
</book>
<book id="0036" bookcategory="文学" amount="100" remain="80"
discount="8.3">
·195·
·196· XML 实用教程
<title>中国文学理论批评史教程</title>
<author>张少康</author>
<publisher>北京大学出版社</publisher>
<ISBN>7-301-04091-1</ISBN>
<price>25</price>
</book>
<book id="0018" bookcategory="计算机" amount="200" remain="100"
discount="8.2">
<title>计算机导论</title>
<author>丁跃潮等</author>
<publisher>高等教育出版社</publisher>
<ISBN>7-04-014768-8</ISBN>
<price>19.7</price>
</book>
<book id="0218" bookcategory="计算机" amount="400" remain="300"
discount="8.5">
<title>程序设计基础</title>
<author>张杰敏主编</author>
<publisher>高等教育出版社</publisher>
<ISBN>7-04-012652-4</ISBN>
<price>17.6</price>
</book>
<book id="0318" bookcategory="计算机" amount="100" remain="60"
discount="8.0">
<title>数据结构与算法</title>
<author>王晓东编</author>
<publisher>高等教育出版社</publisher>
<ISBN>7-04-013204-4</ISBN>
<price>21.8</price>
</book>
<book id="0181" bookcategory="计算机" amount="250" remain="156"
discount="8.0">
<title>XML Web Service 开发</title>
<author>微软公司著</author>
<publisher>高等教育出版社</publisher>
<ISBN>7-04-015825-6</ISBN>
<price>65.00</price>
</book>
<book id="0189" bookcategory="计算机" amount="230" remain="160"
discount="8.0">
<title>VB.NET 程序设计语言</title>
<author>微软公司著</author>
<publisher>高等教育出版社</publisher>
<ISBN>7-04-013188-9</ISBN>
<price>86.00</price>
</book>
<book id="0028" bookcategory="计算机" amount="100" remain="90"
discount="7.5">
<title>JavaScript 速成教程</title>
<author>Michael Moncur 著</author>
<publisher>机械工业出版社</publisher>
·196·
第9章 XML 文档对象模型 ·197·
<ISBN>7-111-09070-5</ISBN>
<price>28.00</price>
</book>
<book id="0074" bookcategory="计算机" amount="130" remain="78"
discount="7.8">
<title>软件工程 Java 语言实现</title>
<author>Stephen R. Schach</author>
<publisher>机械工业出版社</publisher>
<ISBN>7-111-06714-2</ISBN>
<price>51.00</price>
</book>
<book id="0109" bookcategory="计算机" amount="210" remain="160"
discount="8.0">
<title>人工智能</title>
<author>Nils J. Nilsson 著</author>
<publisher>机械工业出版社</publisher>
<ISBN>7-111-04738-6</ISBN>
<price>45.00</price>
</book>
<book id="0305" bookcategory="计算机" amount="115" remain="26"
discount="7.5">
<title>ASP 开发实例</title>
<author>清汉计算机工作室编著</author>
<publisher>机械工业出版社</publisher>
<ISBN>7-980039-74-2</ISBN>
<price>53.00</price>
</book>
</books>
程序 code9_1.htm 的代码是通用的,
对于加载的任何 XML 文件,
都能把与根结点(document
Element)直接相连的每个子结点(objNode)列出来,并把这些子结点下的各层次结点文本值
·197·
·198· XML 实用教程
显示出来。根结点下直接相连的子结点为 documentElement.childNodes。每个循环不需要循
环控制变量,它循环的次数由所涉及的结点集下的结点数决定,这给编程带来了极大的
方便。
注意,XML DOM 技术的运用需要 XML 解析器,因此本章实例在 Windows 系统中运
行需要安装有 MSXML 解析器才能正确显示。常用的 MSXML 解析器是 2003 年 4 月的
MSXML 4.0 sp2 版本。如果已安装有 2001 年 4 月的 MSXML 4.0 试用版,可能导致某些结
果不能正确显示,需要先卸载,命令提示符下的命令为:
regsvr32/u msxml4.dll
·198·
第9章 XML 文档对象模型 ·199·
<table border=1>
<tr><td>结点</td>
<td>内容</td>
</tr>
<script language="JavaScript">
// 建立 XML 元素的字符串
var xmlStr = "<books>"
xmlStr = xmlStr + "<book>"
xmlStr = xmlStr + "<title>三国演义</title>"
xmlStr = xmlStr + "<author>罗贯中</author>"
xmlStr = xmlStr + "<publisher>文艺出版社</publisher>"
xmlStr = xmlStr + "<ISBN>0-764-58007-8</ISBN>"
xmlStr = xmlStr + "<price>80</price>"
xmlStr = xmlStr + "</book>"
xmlStr = xmlStr + "<book>"
xmlStr = xmlStr + "<title>红楼梦</title>"
xmlStr = xmlStr + "<author>曹雪芹</author>"
xmlStr = xmlStr + "<publisher>三秦出版社</publisher>"
xmlStr = xmlStr + "<ISBN>7805468397</ISBN>"
xmlStr = xmlStr + "<price>22</price>"
xmlStr = xmlStr + "</book>"
xmlStr = xmlStr + "<book>"
xmlStr = xmlStr + "<title>西游记(上下册)</title>"
xmlStr = xmlStr + "<author>吴承恩</author>"
xmlStr = xmlStr + "<publisher>人民文学出版社</publisher>"
xmlStr = xmlStr + "<ISBN>7020008739</ISBN>"
xmlStr = xmlStr + "<price>40.12</price>"
xmlStr = xmlStr + "</book>"
xmlStr = xmlStr + "</books>"
var xmlDom = new ActiveXObject("MSXML2.DOMDocument.4.0")
//设置 xmlDom 的 async 为 false,即异步为假,保证 XML 解析器暂停执行,直到 XML 字符串
加载完成
xmlDom.async = "false"
// 加载 XML 文件的字符串
xmlDom.loadXML(xmlStr)
var objNode = xmlDom.documentElement.childNodes
// 显示所有的 XML 结点
for (i=0; i< objNode.length; i++){
document.write("<tr><td>" + objNode.item(i).nodeName + "</td>")
document.write("<td>" + objNode.item(i).text + "</td></tr>")
}
</script>
</table>
</body>
</html>
其显示结果如图 9.3 所示。
·199·
·200· XML 实用教程
·200·
第9章 XML 文档对象模型 ·201·
程序 code9_3.htm 中的<html>、<body>、<head>、<title>几个标记的语句可以去掉,不
影响转换显示的效果。
在 DOM 对象中已经有了一个格式良好的、合法的文档后,就可以用这个文档来进行
结点元素及其属性的处理了。DOM 提供了许多精确分析文档内容的方法。由于 DOM 将文
档内容描述成一棵嵌套结点所组成的树(每个结点由一个元素及其所有子元素构成),所以
处理 XML 数据实际上归结为处理一系列的结点对象。可以用 getElementsByTagName 方法
从文档中获得元素(或结点)。
【例 9.4】 加载 XML 文件并显示所有元素,代码如源程序 code9_4.asp 所示,加载的 XML
文件为 code9_1.xml。
·201·
·202· XML 实用教程
<%@ language="VBScript"%>
<html>
<head>
<title>从服务端加载 XML 文件并显示其所有元素值</title>
<body>
<center><b>服务器端加载的 XML 文件所有元素</b></center>
<hr>
<%
' 建立 XML DOM 对象
set xmlDom = Server.CreateObject("MSXML2.DOMDocument.4.0")
xmlDom.async = "false"
' 加载 XML 文件
xmlDom.load(Server.MapPath("code9_1.xml"))
if xmlDom.parseError.errorCode <> 0 then
Response.Write("加载 XML 文件错误<P>")
else
set objRootNode = xmlDom.documentElement
set objNode = objRootNode.firstChild.childNodes.Item(1)
Response.Write("<TABLE border=1>")
set objListNode = objRootNode.childNodes
' 显示所有的 XML 结点
for i = 0 To objListNode.length - 1
Response.Write("<tr><td>" & objListNode.Item(i).nodeName &
"</td>")
Response.Write("<td>" & objListNode.Item(i).text & "</td></tr>")
next
Response.Write("<table>")
end if
%>
</body>
</html>
·202·
第9章 XML 文档对象模型 ·203·
即可实现在服务器端的处理和向客户端的显示。
【例 9.5】 服务器端同时加载 XML 文件及其转换文件,显示图书信息,代码如源程序
code9_5.asp 所示,XML 文件为 code9_1.xml,转换文件为 code9_1.xslt。显示结果与例 9.3 相
同,如图 9.4 所示。
<meta http-equiv="Content-Type" content="text/html;charset=GB2312">
<%
' 加载 XML 文件
set xmlDom=Server.CreateObject("MSXML2.DOMDocument.4.0")
xmlDom.async="false"
xmlDom.load(Server.MapPath("code9_1.xml"))
' 加载 XSLT 文件
set xslDom=Server.CreateObject("MSXML2.DOMDocument.4.0")
xslDom.async="false"
xslDom.load(Server.MapPath("code9_1.xslt"))
' 转换输出 HTML 文件
Response.Write(xmlDom.transformNode(xslDom))
%>
9.4 parseError 对象
属性名称 说 明
errorCode 返回长整型错误代码
reason 返回字符串型错误原因
line 返回长整型错误行号
linePos 返回长整型错误行号位置
srcText 返回字符串型产生错误原因
url 返回 URL 装载文档指针
filePos 返回长整型错误文件位置
·203·
·204· XML 实用教程
9.4.2 出现错误时的处理
9.5.1 新增 XML 结点
·204·
第9章 XML 文档对象模型 ·205·
表 9-5 建立各类结点的方法
方 法 描 述
CreateElement(elemname) 使用指定名称 elemname 创建元素结点
CreateAttribute(attrname) 创建新属性结点,参数属性名称
CreateCDATASection(text) 创建 CDATA 块,参数 text 为文字内容
CreateComment(text) 创建注释文字结点,参数 text 为注释内容
CreateTextNode(text) 创建文本结点,参数为文字内容
CreateEntityReference(entityref) 创建实体参考对象,参数 entityref 为实体参考名称
CreateProcessingInstruction(target,text) 创建 PI 结点,参数 target 为 PI 名称,text 为值
新增 XML 结点按照建立新结点、将结点插入到位、给元素赋值和添加元素属性的步
骤进行。假设要建立如下的 XML 文档:
<books>
<book id="0001" discount="8.7">
<title>三国演义</title>
<author>罗贯中</author>
<publish>
<publisher>文艺出版社</publisher>
<ISBN>0-764-58007-8</ISBN>
<pubdate>1998.10</pubdate>
</publish>
<price>80</price>
</book>
<books>
可以按下列步骤进行。
1. 建立新结点
XML DOM 对象创建元素的方法为 CreateElement。当使用 CreateElement 方法时,只
需要提供元素名称,如创建元素 books:
set xmlDom=Server.CreateObject("MSXML2.DOMDovument.4.0")’建立文档对象
set objRoot = xmlDom.CreateElement("books")
2. 将结点插入到位
创建了结点,并不意味着它属于哪棵树,必须把它添加进 XML 文档的适当位置上才
行。这就要用 AppendChild 方法,例如,对于上面的例子,可以写出:
xmlDom.AppendChild(objRoot)
·205·
·206· XML 实用教程
3. 给元素赋值
下面的语句是在结点 book 上再建立子结点 title、author,并分别赋予结点文本值:
set newNode= xmlDom.CreateElement("title")
newNode.text="三国演义"
objbook.AppendChild(newNode)
set newNode= xmlDom.CreateElement("author")
newNode.text="罗贯中"
objbook.AppendChild(newNode)
上述代码的后面加上简单的显示语句:
response.write("<xmp>"+xmlDom.xml+"</xmp>")
·206·
第9章 XML 文档对象模型 ·207·
图 9.6 建立新结点的效果
4. 添加元素属性
创建结点之后,还要对其属性赋值。这些属性用来描述结点的标识符或者一些特性值。
创建新属性最直接的办法就是使用 element 对象中的 setAttribute 方法,也可以先用 document
对象中的 createAttribute 方法设置属性值,然后使用 element 对象中的 setAttributeNode 方法
把新结点添加到 DOM 树中。
SetAttribute 方法用来给结点赋属性值,要求属性名和属性值两个参数。在上述代码中
增加几行,可以为 book 元素增加属性:
·207·
·208· XML 实用教程
对于元素结点的删除和替换操作,首先都要对操作对象进行定位,然后相应地执行对
象结点所属父结点的 removeChild 方法,如在例 9.7 中删除 book 结点:
set objDeleteNode=xmlDom.documentElement.firstchild
objRoot.removeChild(objDeleteNode)
·208·
第9章 XML 文档对象模型 ·209·
'定位到 book 结点
set objDeleteNode=xmlDom.documentElement.firstchild
'删除 book 下的 title 结点
objDeleteNode.removeChild(objDeleteNode.getElementsByTagName("title").
item(0))
'得到要删除的属性结点
set DeleteAttrbuteNode=objDeleteNode.getattributeNode("ID")
'删除属性结点 ID
objDeleteNode.removeAttributeNode(DeleteAttrbuteNode)
'再次显示整个 XML 文档
response.write("<br>删除 tilte 结点和 ID 属性之后<br>")
response.write("<xmp>"+xmlDom.xml+"</xmp>")
·209·
·210· XML 实用教程
·210·
第9章 XML 文档对象模型 ·211·
9.6 小 结
9.7 习 题
·211·
·212· XML 实用教程
<address>
<zipcode>123456</zipcode>
<city>厦门市</city>
<street>中山路 2 号</street>
</address>
</customer>
</customers>
6. 在上题的基础上完成以下操作。
(1) 在 registerdate 和 address 元素之间加入 email 元素并赋值 great_sell@163.com。
(2) 在 zipcode 和 city 元素之间加入 province 元素并赋值福建省。
(3) 在 street 元素之后加入 phonenumber 元素并赋值 0592-6688688。
(4) 显示最后结果。
7. 在上题的基础上增加 customer 的 discount 属性,赋值 0.2,并显示结果。
8. 在上题的基础上删除元素 registerdate 和 phonenumber,并显示结果。
·212·
第 10 章 XML 与 Java
10.1 Java 简介
易引发程序错误的地方,如指针的内存管理。Java 提供了丰富的类库,使编程比较容易。
2. 面向对象
Java 的设计集中于对象及其接口,对象中封装了它的状态变量以及相应的方法,实现
了模块化和信息隐藏。而类则提供了一类对象的原型,并且通过继承机制,子类可以使用
父类所提供的方法,实现了代码的复用。它提供了简单的类机制及动态的接口模型,由属
性(状态变量)、方法(函数)和事件(触发机制封装而成),是纯面向对象的编程语言,它不支
持类似 C 语言那样的面向过程的程序设计技术。Java 支持静态和动态风格的代码继承及复
用。
3. 分布式
Java 包括支持 HTTP 和 FTP 等基于 TCP/IP 协议簇的子库。因此,Java 应用程序可凭
借 URL 打开并访问网络上的对象,其访问方式与访问本地文件系统几乎完全相同。为分布
式环境尤其是 Internet 提供动态内容无疑是一项非常困难的任务,但 Java 的语法特性却使
用户很容易实现这项目标。
4. 解释性
Java 解释器(运行系统)能直接运行目标代码指令。链接程序通常比编译程序所需资源
少,因此程序员可以在创建源程序上投入更多的时间。
5. 稳健性
Java 在编译和运行程序时,都要对可能出现的问题进行检查,以消除错误的产生。它
提供自动垃圾收集来进行内存管理,防止程序员在管理内存时容易产生的错误。通过集成
的面向对象的例外处理机制,在编译时,Java 提示可能出现但未被处理的例外,帮助程序
员正确地进行选择以防止系统崩溃。另外,Java 在编译时还可捕获类型声明中的许多常见
错误,防止动态运行时不匹配问题的出现。
6. 安全性
Java 的安全性可从两个方面得到保证。一方面,Java 语言不支持指针和释放内存等 C++
的功能,这样就避免了非法内存操作;另一方面,类装载通过将本机类与网络资源类的名
称分开,来保持安全性。因此调入类时总要经过检查,这样避免了“特洛伊木马”现象的
出现。
7. 结构中立
为了使 Java 作为网络的一个整体,Java 程序将它的程序编译成一种结构中立的中间文
件格式。只要有 Java 运行系统的计算机都能执行这种中间代码。
8. 可移植性
与平台无关的特性使 Java 程序可以方便地被移植到网络上的不同计算机中。同时 Java
的类库中也实现了与不同平台的接口,使这些类库可以移植。另外 Java 编译器是由 Java
语言实现的,Java 运行时系统由标准 C 语言实现,这使得 Java 系统本身也具有可移植性。
·214·
第 10 章 XML 与 Java ·215·
9. 高性能
如果解析器速度不慢,Java 可以在运行时直接将目标代码翻译成机器指令。从而得到
较高的性能。
10. 多线程
Java 提供多线程功能使得在一个程序里可同时执行多个小任务,而且同步机制保证了
对共享数据的正确操作。通过使用多线程可以很容易地实现网络上的实时交互行为。
11. 动态性
Java 的动态特性是其面向对象设计方法的扩展。它允许程序动态地装入运行过程中所
需要的类,这是 C++进行面向对象程序设计所无法实现的。而且 Java 通过接口来支持多继
承,使其比严格的类继承具有更灵活的方式和扩展性。
Java 虽出现的时间不长,但已被业界接受,IBM、Apple、DEC、Adobe、SiliconGraphics、
HP、Oracle、Toshiba、NetScape 和 Microsoft 等大公司已经购买了 Java 的许可证。Microsoft
公司还在其 Web 浏览器 IE3.0 版中增加了对 Java 的支持。
另外,众多的软件开发商也开发了许多支持 Java 的软件产品。如 Borland 公司的基于
Java 的快速应用程序开发环境 Latte;Metrowerks 公司和 Natural Intelligence 公司分别开发
的基于 Machintosh 的 Java 开发工具;Sun 公司的 Java 开发环境 Java Workshop;Microsoft
公司也开发出系列 Java 产品。数据库厂商如 Illustra、Sybase、Versant、Oracle 都在开发支
持 HTML 和 Java 的 CGI(Common Gateway Interface)。在以网络为中心的计算机时代,不支
持 HTML 和 Java,就意味着应用程序的应用范围只能限于同质的环境。
Internet 正在成为企业信息系统最佳的解决方案。它的优点表现在:便宜、易于使用和
管理。用户不管使用何种类型的计算机和操作系统,界面是统一的 Web 浏览器,而数据库、
Web 页面、应用程序(用 Java 编的 applet)则存在 WWW 服务器上。开发人员只需维护一个
软件版本,管理人员省去了为用户安装、升级、培训之苦,用户则只需一个操作系统和一
个 Internet Explorer 足矣。
大家可以设想未来的计算方式,每个 HomePage 的实质是一个多媒体应用程序,这些
程序用 Java 来开发。Java 应用程序运行在异质的计算机、异质的操作系统之上,甚至于电
冰箱、烤面包箱、防盗电子设备之中,用 Internet 把所有的电子设备连接起来,通过 TCP/IP
协议簇进行信息的交流。Java 应用程序之间既可以交换消息,也可以交换程序(一个 Java
的小应用程序 applet)。或许有一天,人们可以在 Netscape 浏览器里查看电冰箱的温度,向
烤面包箱发一个电子邮件。
Java 的出现是计算机信息交换的一个重要里程碑。在单机时代,程序进程之间靠共享
存储进行变量交换;在网络时代,运行在不同主机上的程序按网络协议进行无格式的消息
(二进制字符流)交换,消息的语义由交换程序双方维护;在 Java 时代,运行在网络上的程
序进程,交换的是小应用程序(applet)。小应用程序是什么?它是一个对象,由一组属性和方
法构成,是一个可执行的实体,不仅有数据的状态,而且有定义在数据上的操作。未来可
能进行代理(Agent)交换,代理有一定的智能性,那便是信息交换的更高级阶段。
·215·
·216· XML 实用教程
图 10.1 版权协议界面
·216·
第 10 章 XML 与 Java ·217·
图 10.2 选择安装组件和安装路径的界面
图 10.3 选择浏览器界面
·217·
·218· XML 实用教程
图 10.4 复制文件进行安装的界面
图 10.5 【属性】对话框
·218·
第 10 章 XML 与 Java ·219·
图 10.6 【环境变量】对话框
·219·
·220· XML 实用教程
10.3.1 JAXP 简介
套 件 说 明
Javax.xml.parsers 提供处理 XML 文件的类
Javax.xml.transform 提供处理 XSLT 文件的类
org.xml.sax 这是 SAX 解析器,提供以事件驱动方式解析 XML 文件的 API
org.xml.saxhelpers 提供解析错误处理的相关类,可以帮助程序设计者使用 SAX API
org.w3c.dom 提供支持 DOM 建议规格的套件
·220·
第 10 章 XML 与 Java ·221·
}catch(SAXException se){
·221·
·222· XML 实用教程
//解析过程错误
exception e=se;
if(se.getException()!=null)
e=se.getException();
e.printStackTrace();
}catch(ParserConfigurationException pe){
//解析器设定错误
pe.printStackTrace();
}catch(IOException ie){
//文件处理错误
ie.printStackTrace();
}
}
private static void walkNode(Node anode){
NodeList child=anode.getChildNodes();
printNode(anode);
for(int i=0;i<child.getLength();i++){
Node node=child.item(i);
if(node.hasChildNodes())
walkNode(node);
else
printNode(node);
}
}
private static void printNode(Node anode){
system.out.println(anode.getNodeName()+","+anode.getNodeValue());
}
}
·222·
第 10 章 XML 与 Java ·223·
<phone>0512-61666666</phone>
<street>XX 省 XX 市人民路 616 号</street>
</address>
</customer>
</customers>
·223·
·224· XML 实用教程
方 法 说 明
设置解析器 CDATA 结点转换成 TEXT 文字结点和新增在其相
setCoalesing(boolen)
邻文字结点之后(如果有的话),默认值为 false,true 表示转换
设置解析器展开实体参考的结点,默认值为 true 表示展开,false
setExpandEntityReferencedes(boolen)
表示不展开
setIgnoringComments(boolen) 设置解析器忽略注释文字,默认值为 false,true 表示不忽略
SetIgnoringElementContentWhitespace 设置解析器忽略元素内容为 whitespace 空白字节的结点,默认
(boolen) 值为 false,true 表示忽略
}catch(SAXException se){
//解析过程错误
exception e=se;
if(se.getException()!=null)
e=se.getException();
e.printStackTrace();
}catch(ParserConfigurationException pe){
//解析器设定错误
pe.printStackTrace();
}catch(IOException ie){
//文件处理错误
ie.printStackTrace();
·224·
第 10 章 XML 与 Java ·225·
}
}
private static void walkNode(Node anode){
NodeList child=anode.getChildNodes();
printNode(anode);
for(int i=0;i<child.getLength();i++){
Node node=child.item(i);
if(node.hasChildNodes())
walkNode(node);
else
printNode(node);
}
}
private static void printNode(Node anode){
system.out.println(anode.getNodeName()+","+anode.getNodeValue());
}
}
·225·
·226· XML 实用教程
<email>notknown@yahoo.com</email>
<registerdate>200508</registerdate>
<address>
<zipcode>361021</zipcode>
<phone>0592-6888888</phone>
<street>XX 省 XX 市银江路 108 号</street>
</address>
</customer>
<customer ID="c0500208">
<username>dreamingboy</username>
<password>22345678</password>
<email>greatman@lycos.com</email>
<registerdate>200505</registerdate>
<address>
<zipcode>215006</zipcode>
<phone>0512-61666666</phone>
<street>XX 省 XX 市人民路 616 号</street>
</address>
</customer>
</customers>
结点类型 说 明
NODE_DOCUMENT_TYPE <!DOCTYPE node SYSTEM “code10_2.dtd”>
NODE_PROCESSING_INSTRUCTION <?xml vertion=“1.0”>
NODE_ELEMENT <username>cheaperget</username>
NODE_ATTRIBUTE ID=“c0500103”
NODE_TEXT cheaperget
·226·
第 10 章 XML 与 Java ·227·
·227·
·228· XML 实用教程
4. Element 接口
Element 接口是从 Node 接口继承过来的,它代表了 XML 文档中的元素。Element 接口
提供了访问 DOM 树中元素内容与信息的途径,并给出了对 DOM 树中的元素进行遍历的
支持。
方法描述:
(1) getElementsByTagName(string),通过标记名称获取元素;
(2) getTagName(),获取元素的标记的名称;
(3) getAttributes(string),获取元素的属性,是属性对象列表,属于 NamedNodeMap;
(4) getAttributeNode(string),通过属性的名字得到一个属性类型结点。
5. NamedNodeMap 属性列表对象
NamedNodeMap 对象可以获取元素的属性列表,因为一个元素可能拥有多个属性。可
以使用 getAttributes 获取属性列表。
下面通过一个实例来说明如何使用上述对象和方法来解析 XML 文档。
【例 10.3】 使用 DOM 对象和方法访问 XML 文档的元素与属性,代码如源程序 code10
_3.java 所示,XML 文件为 code10_1.xml。
import javax.xml.parsers.*;
import org.xml.sax.*;
import java.io.*;
import org.w3c.dom.*;
public class code10_3{
static Document document;
public static void main(String[] args){
if(args.length!=1){
system.out.println("加载 XML 文档");
return;
}
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
try{
DocumentBuilder db=dbf.newDocumentBuilder();
//读入 XML 文档
document=db.parse(new File(args[0]));
//获得根元素
Node root=document.getDocumentElement();
//获得根元素的子结点列表
NodeList childs=root.getChildNodes();
getElement(childs);
}catch(SAXException se){
//解析过程错误
Exception e=se;
if(se.getException()!=null)
e=se.getException();
e.printStackTrace();
}catch(ParserConfigurationException pe){
//解析器设定错误
·228·
第 10 章 XML 与 Java ·229·
pe.printStackTrace();
}catch(IOException ie){
//文件处理错误
ie.printStackTrace();
}
}
public static void getElement(NodeList childs){
int i=0;
if(childs.getLength()==0)
{//该结点没有子结点
System.out.println("该结点没有子结点!");
}
for(i=0;i<childs.getLength();i++){
//获取第 i 个子结点
Node node=childs.item(i);
//获取结点的类型,可以是 ElementNode,TextNode,DocumentNode 等
short nodetype=node.getNodeType();
/*ElementNode 类型的结点可包含子结点和属性等*/
if(nodetype==Node.ELEMENT_NODE)
{
//得到结点名称
String name=node.getNodeName();
String attrValue="",attrName="";
system.out.println("this is element! name is:"+name);
if(node.hasAttributes())
{
/*取出一个元素的属性,得到的是一个属性对象列表(NameNodeMap),在此因
为 XML 文档中元素只有一个属性,所以只取 NameNodeMap 中的第 0 个值*/
Node attrNode=node.getAttributes().item(0);
/*取出该属性结点的 Name 和 Value,即是一个 ElementNode 的属性名称和属
性值*/
attrName=attrNode.getNodeName();
attrValue=attrNode.getNodeValue();
System.out.println("this element attr
is:"+attrValue+";attrnameis:"+attrName);
}
//如有子结点,递归调用 GetElement()
if(node.hasChildNodes())
{getElement(node.getChildNodes());}
}
/*Text 类型结点没有子结点,结点名为#text,结点的值为 XML 文档中元素的值*/
if(nodetype==Node.TEXT_NODE)
{
//该结点的 name 是"#text"
String txtName=node.getNodeName();
//取出 Text 类型结点的值
Node thisparent=node.getParentNode();
Node txtNode=thisparent.getChildNodes().item(0);
String txtValue=txtNode.getNodeValue();
if(txtValue.trim().length()>0)
{
·229·
·230· XML 实用教程
system.out.println("txtName="+txtName+";
txtValue="+txtValue.trim());
}
}
}
}
}
例 10.3 使用循环显示了所有的子结点,如果需要访问特定的元素或属性,可以使用
Document 对象的 getElementByTagName 方法获取指定的 XML 元素。如获得 password 标记
的第二个 password 标记,NodeList 结点列表,如下所示:
//获得 password 标记的 NodeList 结点列表
NodeList passwords=Document.getElementByTagName("password");
//item 方法指出为第二个 password 标记
system.out.println("元素名称:"+passwords.item(1).getNodeName());
·230·
第 10 章 XML 与 Java ·231·
表 10-4 建立新结点的方法
方 法 说 明
createAttribute(string) 建立属性名称的属性结点,参数是属性名称
createComment(string) 建立注释文字结点,参数为注释文字内容
createTextNode(string) 建立文字结点,参数为内容
createEntityReference(string) 建立实体参考,参数为实体参考名称
3) 指定插入的位置
在建立好 XML 元素的对象后,可以使用 Node 结点对象的方法添加到 DOM 树中:
z appendChild(newnode),新添加一个 newnode 结点;
z insertBefore(newnode,befnode),将 newnode 结点插到 befnode 结点前。
4) 新增元素内容
使用 createTextNode 方法建立文字结点后,再使用 appendChild 方法将它添加到元素结
点中。
5) 新增元素的属性
可以使用 setAttribute 方法给 Element 元素对象增加属性。
6) 删除元素或属性
如要删除结点可使用 Node 结点的 removeChild 方法删除指定的结点,如要删除属性可
使用 Element 元素对象的 removeAttribute 方法删除。
·231·
·232· XML 实用教程
//删除第一个 customer 结点
root.removeChild(Element)root.getElementsBytagName("customer").item(0)
;
//删除属性
Element node=(Element)root.getFirstChild();
Node.removeAttribute("ID")
·232·
第 10 章 XML 与 Java ·233·
{
//显示元素的名字和元素的内容(文字结点)
system.out.print("元素:"+childs.item(i).getNodeName());
system.out.println("/"+childs.item(i).getFirstChild().
getNodeValue());
//显示元素的的属性值
if(childs.item(i).hasAttributes())
{
//取属性列表
NamedNodeMap atts=childs.item(i).getAttributes();
//使用 for 循环获取各属性名称和值
for(int j=0;j<atts.getLength();j++)
{
Node att=atts.item(j);
System.out.print("--"+att.getNodeName());
System.out.println("/"+att.getNodeValue());
}
}
}
}
}
·233·
·234· XML 实用教程
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import java.io.*;
public class code10_5{
public static void main(String[] args) throws Exception{
//建立 TransformerFactory 对象
TransformerFactory factory=TransformerFactory.newInstance();
//以 XSLT Script 文件作为输入建立 Transformer 对象
Transformer transformer=factory.newTransformer(new
StreamSource("code9_1.xslt"));
//使用 StreamSource 加载 XML 文件
StreamSource xmlsource=new StreamSource("code9_1.xml");
//使用 StreamResult 创建与输出文档 HTML 文件的关联
StreamResult output=new StreamResult(new
FileOutputStream("code10_5.html"));
//转换 XML 文档
transformer.transform(xmlsource,output);
}
}
图 10.11 输出结果
·234·
第 10 章 XML 与 Java ·235·
10.6 小 结
10.7 习 题
·235·
第 11 章 XML 与 ASP
11.1 ASP 简介
·237·
·238· XML 实用教程
Session 还可以创建虚拟购物篮。无论什么时候当用户在网站中选择了一种产品,那么
这种产品就会进入购物篮,当他(她)准备离开时,就可以立即进行以上所有选择产品的订
购,这些购物信息可以被保存在 Session 中。
对 象 说 明
Connection 用来建立与数据库的连接
Command 用来对数据库执行命令,如查询、删除、修改记录等
Recordset 用来得到从数据库返回的记录集
Connection 对象又称连接对象,主要用来建立与数据库的连接。只有建立连接后,才
能利用 Command 和 Recordset 对象对数据库进行各种操作。
Command 对象又称命令对象,是对数据库执行命令的对象,它可以执行对数据库查询、
添加、删除、修改等记录操作。当然,也可利用 Connection 对象的 Execute 方法进行查询、
添加、删除、修改记录等操作,这是一种常用方法。
Recordset 对象又称记录集对象,是最主要的对象。当用 Command 或 Connection 对象
执行查询命令后,就会得到一个记录集对象,该记录集包含满足条件的所有记录。利用
Recordset 对象也可以添加、删除或修改记录。
这 3 个对象看起来逻辑关系还是比较简单的,利用 Connection 对象和数据库建立连接,
然后用 Command 对象执行命令,最后在得到的 Recordset 对象中具体操作。
11.2.1 Connection 对象
Connection 对象是用来连接数据库的。关于该对象,需要注意以下几点。
·238·
第 11 章 XML 与 ASP ·239·
参 数 说 明
User 数据库登录账号
Password 数据库登录密码
Driver 数据库的类型(驱动程序)
Dbq 数据库的物理路径
Provider 数据提供者
2. Connection 对象的属性
Connection 对象有很多属性,常用的属性见表 11-3。
属 性 说 明
·239·
·240· XML 实用教程
续表
属 性 说 明
CursorLocation 控制光标的类型
Mode 设置连接数据库的权根
比较常用的有以下几个。
1) ConnectionString
该属性用于指定 Connection 对象的数据库连接信息。下面的例子也可以建立与数据库
的连接:
<%
dim db
dim strSql
set db=Server.CreateObject("ADODB.Connection")'创建数据库连接对象
StrCon="Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" &
Server.Mappath("address.mdb")
db.Open StrCon'建立与数据库的连接
%>
2) ConnectionTimeout
该属性用于指定 Connection 对象的 Open 方法与数据库连接的执行最长时间。当时间
到了数据库还没有正确连接上,就停止执行。
该属性的默认值为 15s,如果设定为 0,则表示无限期等候直到 Open 方法完成为止。
下面例子将默认值设置为 30s:
<%db.ConnectionTimeout=30%>
同 CommandTimeout 一样,如果服务器比较慢,可以设置连接时间长些。
3) DefaultDatabase
一般的数据提供者只能提供一个数据库,有的数据提供者却能提供多个数据库,用该
属性可以在多个数据库中指定默认的数据库。
3. Connection 对象的方法
Connection 对象有很多方法,都比较有用,其中 Open 方法和 Execute 方法是最常用的
方法。更多的常用方法见表 11-4。
·240·
第 11 章 XML 与 ASP ·241·
方 法 说 明
Open 建立与数据库的连接
Close 关闭与数据库的连接
Execute 执行数据库查询(可以执行各种操作)
BeginTrans 开始事务处理
CommitTrans 提交事务处理结果
RollbackTrans 取消事务处理结果
下面详细介绍。
1) Open
该方法用来建立与数据库的连接。只有用 Open 方法和数据库建立连接后,才可以继
续进行各种操作。
2) Close
该方法用来关闭一个已打开的 Connection 对象及其相关的各种对象。它的作用主要是
用以切断与数据库之间的连接通道。当该通道被关闭后,所有依赖该 Connection 对象的
Command 或 Recordset 对象也将立即被切断关系,方法如下:
<%
db.Close '关闭与数据库的连接
set db=nothing '从内存中彻底清除 Connection 对象 db,也可以省略
%>
说明:其实也可以不用该方法关闭对象,因为当一个页面关闭后,Connection 对象会
自动关闭。不过养成使用完主动关闭的习惯还是很好的,有时可以节省内存资源。
3) Execute
该方法用来执行数据库查询,可以完成几乎所有的功能。它的语法格式有两种:
set Recordset 对象=Connection 对象.Execute(SQL 字符串)
或 Connection 对象.Execute(SQL 字符串)
11.2.2 Recordset 对象
·241·
·242· XML 实用教程
参 数 说 明
默 认 数 值 描 述
LockType 参数 数 值 描 述
AdLockReadOnly 1 只读,不许修改记录集,默认值
AdLockPessimistic 2 只能同时被一个客户修改,修改时锁定,修改完毕释放
AdLockOptimistic 3 可以同时被多个客户修改
AdLockBatchOptimistic 4 数据可以修改,但不锁定其他客户
Options 参数 值 说 明
·242·
第 11 章 XML 与 ASP ·243·
方 法 说 明
Open 打开记录集
Close 关闭当前的 Recordset 对象
Requery 重新打开记录集
MoveFirst 移动到第一条记录
MoveProvious 移动到上一条记录(向后移动)
MoveNext 移动到下一条记录(向前移动)
MoveLast 移动到最后一条记录
Move 移动到指定记录
AddNew 添加新记录
Delete 删除当前记录
Update 更新数据库数据
CancelUpdate 取消数据更新
GetRows 从记录集中取得多行数据
Resync 与数据库服务器同步更新
·243·
·244· XML 实用教程
关闭,语法格式如下:
Recordset 对象.Close
若只有一个字段,则语法格式如下:
Recordset 对象.AddNew 字段名,字段值
·244·
第 11 章 XML 与 ASP ·245·
<html>
<head>
<title>数据库的基本操作</title>
<head>
<body>
<%
'连接数据库,建立 Connection 对象,address.mdb 下面将建立
dim db
dim strSq1,rs '定义变量
set db=Server.CreateObject("ADODB.Connection")
strCon="Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" &
Server.Mappath("address.mdb")
Db.Open StrCon
StrSq1="Select * From users"
'查询记录
'以下建立 Recordset 对象实例 rs
set rs=db.Execute(strSq1)
do while not rs.Eof
Response.Write rs("name") & " " & rs("tel") & " " & rs("age") &
"<br>"
Rs.MoveNext
Loop
%>
</body>
</html>
程序说明:本例主要是为了加深大家对数据库基本操作语法的理解,同时也是强调这
几种方法的重要性。
要使用一个数据库,必须安装和支持一个分离的服务器处理进程,它常要求有安装和
支持它的管理员。必须学习 SQL 语句,并用 SQL 语句写查询,然后转换数据,再返回。
而如果用 XML 文件存储数据,将可以减少额外的服务器负荷。此外还有一个编辑数据的
简单方法。只需使用文本编辑器,而不必使用复杂的数据库工具。XML 文件很容易备份和
下载到客户端。
·245·
·246· XML 实用教程
XML 还有一个更抽象的优点,即作为层次型的格式比关系型的更好。它可以用一种很
直接的方式来设计数据结构以符合需要。不需要使用实体—关系编辑器,也不需要使图表
标准化。如果一个元素包含了另一个元素,可以直接在格式中表示它,而不需要使用表的
关联。
ADO 定义一个完整的功能接口,允许把 Recordset 作为 XML 文件来存取。除了自己编
写 ASP 程序代码浏览 Recordset 然后将各条记录存储为 XML 标记数据之外,还可以通过
Recordset 对象的 save 方法直接将 Recordset 内的记录存储成 XML 格式(文件或网页)。
·246·
第 11 章 XML 与 ASP ·247·
·247·
·248· XML 实用教程
<para>硬件就是构成计算机各部件的实体,是计算机中看得见、摸得到的部分。硬件是
计算机工作的前提。…</para>
</chapter>
</book>
</books>
·248·
第 11 章 XML 与 ASP ·249·
输出当前结点之后,通过递归调用 getallnodes()来获得当前结点子结点的信息,如下
所示:
'获得子结点信息
if node.childNodes.length<>0 then
for i=0 to node.childNodes.length-1
getnodes(node.childNodes(i)
next
end if
·249·
·250· XML 实用教程
·250·
第 11 章 XML 与 ASP ·251·
·251·
·252· XML 实用教程
·252·
第 11 章 XML 与 ASP ·253·
<td><xsl:value-of select="出版社"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
·253·
·254· XML 实用教程
·254·
第 11 章 XML 与 ASP ·255·
AdPersistXML 1 XML 格式
·255·
·256· XML 实用教程
11.4 综 合 实 例
·256·
第 11 章 XML 与 ASP ·257·
图 11.6 留言簿首页列表信息
图 11.7 留言信息
·257·
·258· XML 实用教程
下面,逐步实现留言簿的各个组成部分。
在实现的留言簿中,客户的所有留言保存在一个 XML 文档(messagebase.xml)中。
【例 11.9】 列表显示 XML 文档信息,代码如源程序 index.asp 所示。
<html><head><title>ASP 访问 xml 文件</title>
<meta http-equiv=Content-Type content="text/html; charset=gb2312">
<table width=680 align=center>
<tbody>
<tr>
<td align=middle><br>
<h2><font color=#0f3ccd>使用 ASP 访问 xml 文件 </font></H2>
<hr width=660 color=#f46240 size=1>
</td></tr></tbody></table>
<!--使用 VBScript 语言编写脚本-->
<%@ Language=VBScript %>
<%
'创建用于访问 XML 文档的 DOM 对象 xmldoc
set xmldoc=Server.createObject("Microsoft.XMLDOM")
'使用 load 方法将访问的 XML 文档装入 xmldoc 对象中
xmldoc.load(Server.MapPath("messagebase.xml"))
'使用 selectNodes 方法获得所有'留言'元素的集合 nodes
set nodes=xmldoc.selectNodes("//留言")
'通过判断 nodes 集合中元素的个数(nodes.length)来决定输出
'输出结果使用 response.write 方法返回到客户浏览器中
'输出没有留言的信息
if nodes.length=0 then
Response.write("<center><h1>")
Response.write("***没有留言***")
Response.write("</h1></center>")
Response.end
end if
'在有留言时,输出留言的主题、留言人姓名、E-mail、日期等信息
'以表格的形式输出结果
Response.write("<table border=0 align=center cellpadding=5>")
Response.write("<thead>")
Response.write("<th>主题</th><th>留言人</th><th>E-mail</th><th>日期
</th>")
Response.write("</thead>")
for i=0 to nodes.length-1
Response.write("<tr>")
'取得"主题"
str1=nodes(i).childNodes(0).text
'取得"姓名"
str2=nodes(i).childNodes(1).text
'取得"E-mail"
str3=nodes(i).childNodes(2).text
'取得"日期"
str4=nodes(i).childNodes(4).text
'设置单击主题时执行 getcontent.asp 来获得留言内容
'将留言日期作为查询参数 datatag
·258·
第 11 章 XML 与 ASP ·259·
url="getcontent.asp?datatag="+str4
'输出主题,并将其设置为超文本链接
Response.write("<td>")
Response.write("<a href="+url+" target='_parent'>")
Response.write(str1)
Response.write("</a>")
Response.write("</td>")
'输出留言人姓名
Response.write("<td>"+str2+"</td>")
'输出留言人 email
Response.write("<td>"+str3+"</td>")
'输出留言日期
Response.write("<td>"+str4+"</td>")
next
%>
<br>
<table width=680 align=center>
<tbody>
<tr>
<td colspan="3">
<!--使用 VBScript 语言编写脚本-->
<hr width=660 color=#f46240 size=1>
</td></tr>
<tr>
<td>
<p align="right"><a href="leavedata.htm">留言</a>
</td>
<td>
</td>
<td>
<a href="deletedata.asp">
删除</a>
</td></tr></tbody></table>
</html>
·259·
·260· XML 实用教程
<日期>2005-10-10//2:42:56</日期>
</留言>
<留言>
<主题>XML 可以标注哪些对像? </主题>
<姓名>小鱼儿</姓名>
<email>fish@263.net</email>
<内容>可以标注普通文档、诸如约会记录或采购定单之类的结构记录、具有数据和方法
的对象、数据记录、有关 Web 站点的元内容、图形表示、标准架构实体和类型、Web 上的信息
与用户之间的所有链接等对像。
</内容>
<日期>2004-1-10//2:44:43</日期>
</留言>
<留言>
<主题>XML 和 C、C++语言有何异同?</主题>
<姓名>秦红</姓名>
<email>hong@mail.net</email>
<内容>C 语言、C++以及类似的如 FORTRAN、Pascal、BASIC、Java 等称为程序语言。
XML 则是用来描述文本和数据等信息的标注语言。XML 可用于存储、传输,也可以用于编程以处
理事件。对 XML 而言,没有具体数据对像处理它就毫用处,但有时具体的数据对像是以隐蔽形式
出现的,但这不能说明 XML 可以不针对具体数据对像使用。这样你就可以明白,XML、HTML、
SGML 用于程序其实不起实质性的作用,它们是一种标志,一种标明了数据类型的标志,当程序
用到这些数据类型时,XML 的作用就体现了出来。
</内容>
<日期>2001-11-10//12:48:22</日期>
</留言>
</留言广场>
·260·
第 11 章 XML 与 ASP ·261·
·261·
·262· XML 实用教程
{ alert("请输入留言内容");return; }
else{var contentstr="<内容>"+content.value+"</内容>"}
var sendstr=topicstr+namestr+emailstr+contentstr
图 11.8 留言簿页面
·262·
第 11 章 XML 与 ASP ·263·
删除留言的页面和留言簿首页类似,只是在每一条留言信息后多了一个用于调用删除
留言程序的超文本链接,如图 11.9 所示。
·263·
·264· XML 实用教程
图 11.9 删除留言页面
·264·
第 11 章 XML 与 ASP ·265·
11.5 小 结
11.6 习 题
·265·
·266· XML 实用教程
ASP 程序,并列表显示全班同学的信息。
5. 编写 ASP 程序把 Access 中的同学通讯录信息生成 XML 文件。
6. 论述为什么要采用 XML 存放数据,其有何优点。
7. 模仿实例程序,编写存放全班同学信息的 XML 文件,并制作全班同学通讯录程序,
编写代码使之能够列表查阅全班同学通讯录、添加同学信息和删除同学信息。
·266·
第 12 章 ebXML 简介
12.1 ebXML
12.2.1 消息传送
·268·
第 12 章 ebXML 简介 ·269·
的电子商务的消息收发服务。该规范旨在实现低成本解决方案,同时使厂商能够通过增强
可靠性和性能提高运营质量。
1. ebXML 消息收发服务规范的主要功能
ebXML 消息收发规范规定:通过数据通信装置传输 ebXML 消息使用的 ebXML 消息
报头和组装要求。它主要定义使用现有的通信协议,在两种 ebXML 消息服务之间传送消
息所需要的基本功能。它将规定 ebXML 以能够实现的可靠性、持久性、安全性和扩展性
的方式,执行消息收发服务。因此,规范将为开发组装、交换和处理 ebXML 消息的软件
提供细则。
2. ebXML 消息收发服务规范的组成要素
ebXML 消息收发服务规范由以下 5 个部分组成:
(1) 消息组装。提供组装一条 ebXML 消息和相关部件的方法,其中包括各种结构和容
器规范。消息组装规范是由 XML 消息报头和消息内容这两部分组成的多方相关标准结构。
消息内容可能是任意一种类型的数据。基于 XML 的消息报头要素及其结构可以根据目前
的专用和通用传送协议进行筛选,以保证报头元素的适用性。
(2) 消息报头。信息结构与合成的一种规范,是 ebXML 消息收发服务成功地产生和处
理 ebXML 的消息所必需的。
(3) 可靠的消息收发。这一功能定义可操作的协议,使任意两种消息实施办法能够交
换通过“可靠的消息收发”语义发送的消息。
(4) 差错控制。这一功能为检测 ebXML 收发服务提供一种报告差错的方法。
(5) 安全性。这一功能在消息内容规范中能够支持有限的安全业务,可以采用适合消
息内容形式的密码技术,给多方相关的消息内容加密。
3. ebXML 消息结构
一条 ebXML 消息由两部分组成,即外部通信协议封装和内部通信协议封装。前者封
装诸如 HTTP 或 SMTP 等协议;后者包括消息的两个主要组成部分,即封装一个 ebXML
报头文件使用的 ebXML 报头内容和封装消息的实际内容(传送的数据)必须使用的单个
ebXML 消息内容容器。
一条 ebXML 消息内容包含 3 种属性:类型属性,使用 MIME 类型属性将按照 ebXML
依从结构识别 ebXML 消息封装,确认 XML 媒体类型;边界属性,用于识别消息中所包含
的每个实体部分起点和终点的分隔符;版本属性,用于识别所使用的 ebXML 消息封装的
特殊版本。
12.2.2 商务处理流程和信息建模
元模型提供了一种机制,它有助于贸易伙伴在指定的商务情节下通过统一的建模理论
来抓住细节。商务处理流程描述了贸易伙伴如何担当角色、表述关系和承担责任,以及如
何与同一个商务处理流程中的其他贸易伙伴进行联系和交互。不同角色之间的交互可以看
成是一连串设计好的商务交易。每次商务交易都可以表示为电子商务文档的一次交换。交
换顺序由商务处理流程、消息传输和安全因素所决定。商务文档则由可重用的商务信息组
·269·
·270· XML 实用教程
件组成。从更低的层次上看,商务处理流程可以理解为可重用的核心处理过程,而商务信
息对象可以理解为可重用的核心组件。
商务处理流程和信息元模型从需求、 分析和设计 3 个角度出发,
分别提供了一组语义(词
汇表),从而形成了推动商务处理流程和信息集成与互操作发展的基本规范。
从元模型的另外一个方面,规范模式也被用来直接实现规范,它可以使用一组元素来
规划进行 ebXML 商务交易的实时系统。通过从其他几个视图中提取建模元素,规范模式
形成商务处理流程和信息元模型的一个语义子集。它可以采用两种独立的表示方法:UML
描述和 DTD。
规范模式支持商务交易的规范以及从商务交易到商务合作的转换。每个商务交易都可
以用众多可用的标准模式来实现。这些模式决定了贸易伙伴之间实际进行的消息和信号交
换。为了有助于阐述这些模式,规范模式总是伴随着一组标准模式及其相关的一组通用建
模元素。因此一个商务处理流程的全部规范包括一个规范模式指定的商务处理流程和信息
元模型及一个所需模式的标志。这些信息成为形成合作协议描述(CPP)和合作方案协议
(CPA)的主要来源。
当构造一个新的商务处理流程时,并不一定要使用建模语言,但如果要用到某种建模
语言,那么应该是统一建模语言 UML。这种强制目的保证在创建商务处理流程时能采用统
一的建模方法。使用统一的建模方法的好处之一是可以比较模型,以避免现有商务处理流
程的重复。
为了保证创建统一的商务处理流程和信息模型,ebXML 将定义一组与核心库对应的通
用核心商务处理流程。ebXML 用户可以扩展这组核心商务处理流程或使用自己的流程。
阐述商务处理流程文档时应当采用一种人和应用程序都能读懂的形式。必须要经过一
个渐进的过渡才能达到商务交互的完全自动处理。
商务处理流程应该通过 Registry 机制发现和获取。为了方便发现和获取,商务处理流
程可以在 Registry 中注册登记。
为了能够被应用程序“理解”,商务处理流程应该用 XML 表示。商务处理流程应该
构造成一个商务处理流程和信息元模型或基于 XML 的表示方式。它能够表达以下类型的
信息:
(1) 交换文档实例的流程设计;
(2) 对商务处理流程和信息元模型或商务文档的引用(可能是 DTD 或 Schema ),对商
务数据引入结构;
(3) 为商务处理流程中每个参与者定义的角色。
一个商务处理流程应提供核心组件使用时的上下文约束,提供建立 CPA 时的框架,
指明商务处理流程的所有者和有关联系信息。
12.2.3 贸易伙伴草案和协定
为了更方便地引导电子商务的运作,潜在的贸易伙伴需要一种机制对外发布他们所支
持的商务处理流程以及交换商务信息的技术实现细节,这可以通过 CPP 实现。CPP 是一个
文档,贸易伙伴可以用来表达所能够支持的商务处理流程和商务服务接口,这种方式也能
够被其他 ebXML 兼容的贸易伙伴所理解。
·270·
第 12 章 ebXML 简介 ·271·
CPP 描述了贸易伙伴具体的技术能力以及为交换商业文档所提供的服务接口。CPP 中
包含贸易伙伴的基本信息,它可以包含但不限于:合同信息、行业分类、支持的商务处理
流程、接口需求和消息服务需求,还可以包括安全性和其他具体的实现细节。每个贸易伙
伴都应该在一个 ebXML 兼容的 Registry 系统中注册它们的 CPP,这样就可提供一种发现
机制用于贸易伙伴之间互相查找,发现其他贸易伙伴支持的商务处理流程。CPP 定义中对
于存在多种实现可能(如 HTTP 或 SMTP)时,应该明确指定使用哪一种选择。
CPA 是描述两个或多个 CPP 交集的文档,希望通过 ebXML 进行电子商务的贸易伙伴
各方对此都表示同意。CPA 描述了消息服务,双方或多方同意的商务处理流程需求。从概
念上讲,ebXML 支持一个嵌套模式的 3 层视图来达成 CPA,从外到内依次是一个贸易伙伴
所有可能做的、能够做的以及实际将要做的,内层是外层的子集。
一个 CPA 包括消息服务接口需求和贸易伙伴双方都同意用于引导电子商务的商务处
理流程的实现细节。贸易伙伴可以在 ebXML 兼容的 Registry 服务中注册他们的 CPA,但
这并不是 CPA 创建过程的必要部分。
商务合作是贸易伙伴首先要声明支持的,由一个单独的描述来表示对特定商务合作的
支持声明,它主要用于在一个目录服务中发布,例如一个 ebXML Registry 或其他可用服务。
12.2.4 注册表
·271·
·272· XML 实用教程
12.2.5 核心组件
ebXML 核心组件提供行业间的互操作性和商务性能,核心组件作用于单个的数据元素
级别。核心组件识别商家最常使用和跨行业的数据项,给它们分配中立的名字和唯一的标
识符。通过核心组件,企业能够将一个行业的数据同另一个行业中相似的数据对应起来,
或从一个 XML 术语对应到早先定义的 EDI 交易。
核心组件用于捕捉现实世界中商务概念里的信息以及这些概念与上下文之间的联系。
所谓的上下文描述了一个核心组件或集成组件在特定的 ebXML 电子商务场景中应如何使
用。一个核心组件可以是一个独立的商务信息块,也可以由一组能够封装在一起的商务信
息块组成,即集成组件。ebXML 核心组件工程小组应该定义一组基本的核心组件,这样
ebXML 用户可以使用这个核心库或者对其进行扩展。
12.3.1 实现阶段
12.3.2 发现和获取阶段
·272·
第 12 章 ebXML 简介 ·273·
12.3.3 实时运行阶段
12.4 ebXML 展望
12.4.1 电子商务全球化解决方案
全球化解决方案是当今更加扩大的市场运营的关键技术。ebXML 的基本目的是促进国
际贸易。为了实现有利于国际贸易的“单一的全球市场”,关键的问题是简化现有的交换标
准技术,并与不同交易方式相协调。这种简化和协调性可通过与核心部件相结合的方式开
发商务元结点得以实现,从而适应不同国家和多国商务过程的需求,并支持向前和向后兼
容 ebXML 的技术框架。而且所有的 ebXML 技术规范应能由某种语言(如英语)转换成其他
的自然语言。
12.4.2 可用性和互通性
ebXML 技术规范的可用性和互通性是商务全球化最基本的要求。可用性和互通性的组
成要素包括结构、传输、路由和组装、可扩展性以及适当利用现有技术,而 ebXML 结构
是其中最主要的要素。
ebXML 结构将支持整个商务过程,包括参与数据交换的双方必须在商务过程上下文连
接方面执行相同的事务处理;共同的语义,即单词表述或表示形式不同而意义相同;共同
的词汇,即单词和意义之间直接通信;共同的字符编码;共同的表述,即 XML 元素名称、
属性和这些元素的利用、文件构成的方法都相同;共同的保密措施;共同的数据传送协议
以及共同的网络层。
商业企业看中的是其应用和贸易伙伴应用之间的最大的互通性。这种互通性凭借从事
商务的单一的电子方式,即将 ebXML 用于电子商务的单一的标准得以实现,但是许多商
业企业在基于现有标准的 EDI 和新的 XML 商务方面有相当多的投入。这些企业需要一种
容纳基于现有标准的传统 EDI 解决方案和 XML 解决方案的机制迁移途径。ebXML 不仅提
供从现有的 EDI 和 XML 解决方案迁移的途径,而且能够保证在开发 ebXML 技术规范方
面优先实现最大程度的互通性。
12.4.4 安全性保证
安全性主要体现在会话层,即网络交换数据的会话期间要求保证安全性,或对独立应
用的文件实例应用安全性规范。而且,安全性规范应用于特殊的数据交换或文件实例时,
·273·
·274· XML 实用教程
还必须根据商务需求而确定,并能默认不受限制和非密的数据交换。在特殊的商务信息交
换中,可能要求多种类型的安全功能。
12.5 小 结
12.6 习 题
1. 什么是 ebXML?
2. ebXML 的任务是什么?
3. 简述 ebXML 的技术体系结构。
4. 简述 ebXML 的应用过程。
·274·
第 13 章 XML 与.NET 构建小型 Web 应用
13.1.1 .NET 构架
·276·
第 13 章 XML 与.NET 构建小型 Web 应用 ·277·
既然 XML 是一种标记语言,就应该有一种工具按一定的语法来分析和理解存储在文
档中的信息。这个工具就是 XML 分析器。
所有的 XML 分析器,不管它属于哪个操作平台,不外乎是以下两类:基于树或者基
于事件的处理器。这两类通常都用 XMLDOM(the Microsoft XML Document Object Model)
和 SAX(Simple API for XML)来实现。XMLDOM 分析器是一个普通的基于树的 API,它把
XML 文档当成一个内存结构树呈现,SAX 分析器是基于事件的 API,它处理每个在 XML
数据流中的元素(它把 XML 数据放进流中再进行处理)。通常,DOM 能被一个 SAX 流载入
并执行,因此,这两类的处理不是相互排斥的。
总的来说,SAX 分析器与 XMLDOM 分析器正好相反,它们的分析模式存在着极大的
差别。XMLDOM 被很好地定义在它的 functionalition 集合里面,不能对其进行扩展。当处
理一个大型的文档时,它要占用很大的内存空间来处理 functionalition 这个巨大的集合。
SAX 分析器则利用客户端应用程序, 通过现存的指定平台的对象实例去处理分析事件。
SAX 分析器控制整个处理过程,把数据“推出”到处理程序,该处理程序依次接受或拒绝
处理数据。这种模式的优点是只需占用很小的内存空间。
.NET Framework 完全支持 XMLDOM 分析器,但不支持 SAX 分析器。因为.NET
Framework 支持两种不同的分析模式:XMLDOM 分析器和 XML 阅读器,它显然不支持
SAX 分析器,但这并不意味着它没有提供类似 SAX 分析器的功能。通过 XML 阅读器 SAX
的所有功能都能很容易的实现并更有效的运用。与 SAX 分析器不同,.NET Framework 的
整个阅读器都运作在客户端应用程序下面。这样,应用程序本身就可以只把真正需要的数
据“推出”,然后从 XML 数据流中跳出来,而 SAX 分析模式要处理所有对应用程序中
有用和没有用的信息。
阅读器是基于.NET Framework 流模式工作的,它的工作方式类似于数据库的游标。有
趣的是,实现类似游标分析模式的类提供对.NET Framework 中 XMLDOM 分析器的底层支
持。XmlReader、XmlWriter 两个抽象类是所有.NET Framework 中 XML 类的基础类,包括
XMLDOM 类、ADO.NET 驱动类及配置类。因此在.NET Framework 中有两种可选的方法
去处理 XML 数据:用 XmlReader 和 XmlWriter 类直接处理 XML 数据,或者用 XMLDOM
分析器处理。
·277·
·278· XML 实用教程
·278·
第 13 章 XML 与.NET 构建小型 Web 应用 ·279·
在 XML 文件中定义的关系的列表,按嵌套顺序排序(从最外到最内)。【数据】区域是根
据【数据表】区域中的选定内容显示数据的数据网格。
另一个是 XML 视图(如图 13.3 所示),提供用于编辑原始 XML 的编辑器,并且提供
智能感知和颜色编码。当处理 XSD 文件和具有关联架构的 XML 文件时可以使用语句完成
功能。输入“<”以开始一个标记,将会提供在该位置有效的元素列表。输入元素名并按
Space 键后,将会看到该元素支持的属性列表。
·279·
·280· XML 实用教程
·280·
第 13 章 XML 与.NET 构建小型 Web 应用 ·281·
·281·
·282· XML 实用教程
·282·
第 13 章 XML 与.NET 构建小型 Web 应用 ·283·
所有 XmlTextReader 类的构造函数都要求指定数据源调用。一旦读取对象创建完毕,
就可以调用其 Read 方法来读取文档。Read 方法顺序读取数据段,每段数据类似于 XML
树的结点,NodeType 属性包含了该段数据的类型,Name 属性包含了结点的名称,Value
属性包含结点的值(若有值的话)。然后使用下列语句来输出信息。
Response.write(myRdr.NodeType.ToString()+" "+
_myRdr.Name+":"+myRdr.Value)
1. 解析 XML 文档
下面给出一个完整的实例,说明应用 XmlTextReader 类解析和显示 books.xml 文件。将
其中的信息显示在 Web 页中。
【例13.2】 使用 XmlTextReader 类解析并显示 books.xml 文件,代码如源程序 xmlText
Reader1.aspx 所示。
<%@ Page language="VB" debug="true" %>
<%@ Import Namespace="System.Xml" %>
<html>
<script runat="server">
sub Page_Load(sender as Object, e as EventArgs)
dim myRdr as New XmlTextReader(Server.MapPath("books.xml"))
dim i as integer
while myRdr.Read()
Response.Write(myRdr.NodeType.ToString()+":"+myRdr.Name _
+":"+myRdr.Value+"</br>")
if myRdr.HasAttributes Then
for i=0 to myRdr.AttributeCount-1
myRdr.MoveToAttribute(i)
Response.Write(myRdr.NodeType.ToString()+":"+myRdr.Name_
+":"+myRdr.Value+"</br>")
next i
·283·
·284· XML 实用教程
myRdr.MoveToElement()
end if
end while
myRdr.Close()
end sub
</script>
<body style="font: 10pt verdana"></body>
</html>
图 13.7 代码的部分输出
·284·
第 13 章 XML 与.NET 构建小型 Web 应用 ·285·
·285·
·286· XML 实用教程
And myRdr2.Name="price")
unitPrice=Double.Parse(myRdr2.ReadString())
lblPrice.Text="Unit Price =" +Formatcurrency(unitPrice)
exit do
end if
end if
myRdr2.Read()
loop
end sub
图 13.10 部分输出
·286·
第 13 章 XML 与.NET 构建小型 Web 应用 ·287·
·287·
·288· XML 实用教程
myWriter.Writecomment("XmlTextWriter Example")
myWriter.WriteStartElement("CustomerDetails")
myWriter.WriteAttributeString("AccountNumber","Saving")
myWriter.WriteStartElement("AccountNumber","")
myWriter.WriteString(txtAcno.Text)
myWriter.WriteEndElement()
myWriter.WriteStartElement("Name","")
myWriter.WriteString(txtName.Text)
myWriter.WriteEndElement()
myWriter.WriteStartElement("City","")
myWriter.WriteString(txtCity.Text)
myWriter.WriteEndElement()
myWriter.WriteEndDocument()
myWriter.Flush()
myWriter.Close()
Response.Redirect ("Customer.xml")
end sub
</script>
1. 加载并保存 XML 文档
·288·
第 13 章 XML 与.NET 构建小型 Web 应用 ·289·
2. 遍历 XML 文档
把 XML 文档看成是一棵树,可以使用 XmlDocument 对 XML 文档进行遍历,下面的
例子主要是遍历 DOM 树并显示每个结点包含的信息。遍历的结果如图 13.11 所示。
图 13.11 遍历的结果
这里,实现了以下两个过程。
(1) DisplayNode:传递一个结点参数,并检查它是不是终端结点或者有没有包含属性。
如果有的话则打印结点内容。
(2) TravelDownATree:传递一棵树,采用先序遍历方式,首先调用 DisplayNode,显示
根结点信息,然后递归调用自己访问子树。
【例 13.5】 用 XmlTextWriter 类书写 XML 文档的示例。
<%@ Page Language = "VB" Debug="True" %>
<%@ Import Namespace="System.Xml" %>
<script language="vb" runat="server" >
sub Page_Load(s as Object, e as EventArgs)
if not Page.IsPostBack then
·289·
·290· XML 实用教程
3. 使用 XmlDataDocument 类
XmlDataDocument 类是 XmlDocument 类的扩展,它最吸引人的一点是提供了同一数据
的两种可选择的视图:XML 视图和关系视图。XmlDataDocument 拥有一个称为 DataSet 的
属性,通过该属性可以将数据分解为一个或多个相关或不相关的数据表。一旦加载了一个
XmlDataDocument 对象,就可以通过 DataSet 属性把它当做 DOM 树或者把它的数据当做一
个数据表(或是数据表的集合)使用。当把数据当做 DOM 树时,与 XmlDocument 类访问 DOM
树的行为方式是一样的。下面举例示例如何从 XmlDataDocument 的 DataSet 数据表视图中
获取数据,结果如图 13.12 所示。
·290·
第 13 章 XML 与.NET 构建小型 Web 应用 ·291·
·291·
·292· XML 实用教程
数据库用来存储和管理企业的数据,将数据从数据库传送给远程客户端和业务伙伴时,
特别是不清楚客户端将如何使用数据时,传统方法就显得比较困难。用 XML 文档发送所
需的数据,就使得数据的容器与客户端的平台无关。数据库和其他的相关数据存储方式还
在,XML 不会替代它们,但 XML 将提供一种在源和目标之间交换数据的通用媒介。XML
也使得不同软件之间能够交换数据。在此背景下,XML 在 ADO.NET 同其他程序间建立了
一座桥梁。由于.NET Framework 集成了 XML,在.NET 中用 XML 交换数据要比其他的软
件开发环境容易。数据可以通过 XML 从一个数据源转换到另一个。.NET Framework 主要
基于 DataSet 类,因此它非常依赖 XML 体系结构,DataSet 类具有许多处理 XML 的方法,
其 中 常 用 的 有 ReadXml 、 WriteXml 、 GetXml 、 GetXmlSchema 、 InferXmlSchema 、
ReadXmlSchema 和 WriteXmlSchema。
下面的两个例子就是让 XML 和数据库进行协同工作。第一个例子中,将用 SQL 查询
创建一个数据集,并把它的内容写成 XML 文档的形式。第二个例子中,将读回第一个例
子所产生的 XML 文档并加载一个数据集。
1. 用查询数据库创建 XML 文档
首先用 Access 数据库中查询到的书籍结果来填充数据集。当单击一个按钮时,写出
XML 文件和它的模式文件。这里可以采用 WriteXml 和 WriteXmlSchema 方法来完成创建
文档的任务。生成的 XML 文档格式如下:
·292·
第 13 章 XML 与.NET 构建小型 Web 应用 ·293·
<myXMLBooks>
<dtBooks>
<BookID>1</BookID>
<Title>三国演义</Title>
<Author>罗贯中</Author>
<Price>24</Price>
<Quantity>5</Quantity>
</dtBooks>
</myXMLBooks>
·293·
·294· XML 实用教程
(Server.MapPath("myXMLData.xml"),FileMode.Create,FileShare.ReadWrite
)
dim myFs2 as new FileStream _
(Server.MapPath("myXMLData.xsd"),FileMode.Create,FileShare.ReadWrite
)
dim myDataSet As new DataSet
myDataSet=Session("sessDs")
'使用 DataSet 的 writeXml 方法把 DataSet 数据输出到 XML 文档
myDataSet.WriteXml(myFs1)
myFs1.Close()
myDataSet.WriteXmlSchema(myFs2)
myFs2.Close()
end sub
</script></body></html>
2. 将 XML 文档读入数据集
前面的例子利用 DataSet 来创建 XML 文档,那么,下面的例子则是将 XML 文档读入到
数据集中。这可以利用 ReadXml 方法来读取 XML 文档,加载到数据集中,结果如图 13.14
所示。
·294·
第 13 章 XML 与.NET 构建小型 Web 应用 ·295·
(Server.MapPath("myXMLData.xml"),FileMode.Open,FileShare.ReadWrite)
myDataSet.ReadXml(myFs)
myGrid.DataSource=myDataSet.Tables(0)
myGrid.DataBind
myFs.close
end if
end sub
</script>
13.4.1 网上书店项目概述
·295·
·296· XML 实用教程
图 13.15 网上书店完成后的用户界面
13.4.2 网站后台数据文件
·296·
第 13 章 XML 与.NET 构建小型 Web 应用 ·297·
<resume>滚滚长江东逝水,浪花淘尽英雄。是非成败转头空。青山依旧在,几度夕阳红。
白发渔樵江渚上,惯看秋月春风。一壶浊酒喜相逢。古今多少事,都付笑谈中。
</resume>
<image_path>bookimage/1.bmp</image_path>
<category>1</category>
</book>
</books>
·297·
·298· XML 实用教程
13.4.3 网站站点架构
设计好后台数据文件以后,现在再来设计网站中间层的业务数据层和界面,这是建立
网上顾客与商店之间的桥梁,网站的结构如图 13.16 所示。
图 13.16 网上书店结构图
13.4.4 具体实现
1. 加载书籍信息
·298·
第 13 章 XML 与.NET 构建小型 Web 应用 ·299·
图 13.17 用户登录后网上书店首页
书籍分类信息使用一个列表框控件,直接把分类信息加载到列表框即可:
ds.ReadXml(Server.MapPath("data\\categories.xml"))
for i = 0 To ds.Tables(0).Rows.Count - 1
ddlcat.Items.Add(ds.Tables(0).Rows(i).Item(1))
next
2. 顾客登录
顾客要选购图书,则必须先进行登录,否则就无法选择图书。当顾客登录完后,后继
的订购过程都是以该用户为中心,需要全程保存用户的信息,可以使用 Session 来保存。验
证用户登录,只是一个简单的比较过程:
ds.ReadXml(Server.MapPath("data\\users.xml"))
for i = 0 to ds.Tables(0).Rows.Count - 1
if (ds.Tables(0).Rows(i).Item(1) = usernametxt.Text) then
'成功,使用 session 记录用户信息
Session("username") = Me.usernametxt.Text
Session("id") = ds.Tables(0).Rows(i).Item(0)
'处理界面,显示顾客信息
oklab.Text = "欢迎您"
usernametxt.Visible = false
passwordtxt.Visible = false
userlab.Visible = false
·299·
·300· XML 实用教程
passlab.Visible = false
userinfolab.Visible = true
userinfolab.Text = "用户:" & Session("username")
loginbtn.Text = "退出"
regbtn.Visible = false
exit for
end if
next
3. 书籍选购
当顾客选择某一书时,需要把书籍信息放入购物车。也可能顾客还没有登录,所以开
始时需要先判断顾客登录与否。
if CChar(Session("username")) = "" then
Response.Write("<script language=javascript>alert('对不起!你
还未登录,不能购买,请先登录!
');window.location.href='index.aspx';</script>")
Response.End()
else
…
end iF
·300·
第 13 章 XML 与.NET 构建小型 Web 应用 ·301·
4. 实现购物车
购物车存放用户选择的书籍及需要购买的数量等信息。用户通过购物车界面能够管理
购物车中的物品,包括删除和更改购买数量等。使用 DataGrid 控件来显示用户已经订购的
商品。
当页面加载时,或者用户进行删除、更改购买数量等操作时,都要重新初始化购物车,
必须更新购物车信息,显示用户已经订购的书籍信息。
private sub updatashopcart()
dim orderlist as ArrayList
dim qtylist as ArrayList
dim i as Integer
dim bookisbn as String
dim book as DataRow
dim tot as Double
dim ordertable as DataTable = New DataTable("ordertable")
'创建新行和列
dim ordercol as DataColumn
dim orderrow as DataRow
'创建数据列
'==书名
ordercol = New DataColumn
ordercol.DataType = System.Type.GetType("System.String")
ordercol.ColumnName = "bk_name"
ordertable.Columns.Add(ordercol)
'==数量
ordercol = New DataColumn
ordercol.DataType = System.Type.GetType("System.Int32")
ordercol.ColumnName = "bk_num"
ordertable.Columns.Add(ordercol)
'==单价
ordercol = New DataColumn
ordercol.DataType = System.Type.GetType("System.Double")
ordercol.ColumnName = "bk_price"
ordertable.Columns.Add(ordercol)
'==小计
ordercol = New DataColumn
ordercol.DataType = System.Type.GetType("System.Double")
ordercol.ColumnName = "bk_total"
ordertable.Columns.Add(ordercol)
'创建数据行
orderlist = Session("orderlist")
qtylist = Session("qtylist")
'
tot = 0
for i = 0 to orderlist.Count - 1
bookisbn = orderlist(i)
book = getbookrow(bookisbn)
orderrow = ordertable.NewRow
orderrow("bk_name") = book("title")
·301·
·302· XML 实用教程
orderrow("bk_num") = qtylist(i)
orderrow("bk_price") = book("price")
orderrow("bk_total") = book("price") * qtylist(i)
ordertable.Rows.Add(orderrow)
'统计总金额
tot += book("price") * qtylist(i)
'
next
DataGrid1.DataSource = ordertable.DefaultView
DataGrid1.DataBind()
'显示总金额
Me.totlab.Text = String.Format("{0:C}", tot)
end sub
另外,用户完成选购时,点击“购买”链接,把用户的订购信息保存起来,以备后台
管理人员根据订单发送书籍。
ds.ReadXml(Server.MapPath("data\\orders.xml"))
Dim rowNew1 As DataRow = ds.Tables(0).NewRow()
Dim rowNew2 As DataRow = ds.Tables(1).NewRow()
orderlist = Session("orderlist")
qtylist = Session("qtylist")
‘记录用户信息
rowNew1("username") = Session("username")
rowNew1("date") = Today
ds.Tables(0).Rows.Add(rowNew1)
'循环记录用户订购书籍的信息
For i = 0 To orderlist.Count - 1
book = Me.getbookrow(orderlist(i))
rowNew2("username") = Session("username")
rowNew2("isbn") = book("isbn")
rowNew2("title") = book("title")
rowNew2("quantity") = qtylist(i)
rowNew2("price") = book("price")
ds.Tables(1).Rows.Add(rowNew2)
rowNew2 = ds.Tables(1).NewRow()
Next
'建立两张表之间的嵌套关系
dim dr as new DataRelation("orderrelation",_
ds.Tables(0).Columns("username"), ds.Tables(1).Columns("username"))
dr.Nested = True
ds.Relations.Add(dr)
ds.WriteXml(Server.MapPath("data\\orders.xml"),
XmlWriteMode.IgnoreSchema)
Response.Write("<script language=javascript>alert('您已成功订购了!
10 天后您将收到你所要图书!');window.location.href='index.aspx';</script>")
Response.End()
·302·
第 13 章 XML 与.NET 构建小型 Web 应用 ·303·
图 13.18 购物车的界面
13.5 小 结
·303·
·304· XML 实用教程
13.6 习 题
第 1 部电影
名称 简介 时间 类型
致命摇篮 李连杰最新力作 2003 动作片
·304·
参 考 文 献