社区应用 最新帖子 精华区 社区服务 会员列表 统计排行
主题 : 转-->XML快速了解
级别: 圣骑士
显示用户信息 
0  发表于: 2002-03-10   

转-->XML快速了解

[font=verdana]
严格的语法
网络在中国发展到今天,一定有很多人或多或少的接触过HTML语言,这是一种不甚严格的语言(也可
以讲是浏览器大战的恶果),很多时候我们直接看到的效果并非是我们的代码表现出来的效果,而是
浏览器很善意的向你们屈服,将一些不完全的代码也正常显示......然而,XML显然不吃这一套,由
于她主要用来存储和发送数据信息,所以她的语法规则必然要求的非常严格,不过严格归严格,学习
起来到是非常的容易---而且使用也同样的简单.基于这个原因,我们可以轻易的建立可以读取和维
护XML的应用软件.

让我们来看一段简单的XML代码:

<?xml version="1.0" encoding="GB2312"?>
<我的故事>
<作者>Jsper</作者>
<出版社>unkown</出版社>
<体裁>个人传记</体裁>
</我的故事>

代码的第一行是XML声明,并且定义XML的版本,目前发布的是1.0版本
代码的第二行是这端代码内容的根元素.是XML所必须声明的元素.
代码的3-5行是根元素的子元素,在这里有三个子元素(作者,出版社,体裁)
最后一行的代码则定义了根元素的结束,到这里,一段完全的XML代码就算完成

细心的人从上面的例子看出,所有的元素都要有闭合标记,这并非是一个巧合我们开始就讲到XML语
法规则非常严格,这就是她的具体表现---所有的元素必须有闭合标记---

e.g: 在HTML语法中,这样的代码是允许存在的...

<p>我的故事是什么呢?
<p>我忘记了

然而在XML语法中,则需要闭合所有元素,于是代码如下
<p>我的故事是什么呢?</p>
<p>我忘记了</p>

一旦没有闭合元素代码,比如在这段代码中如果我们漏掉</p>,那么这段代码将是一段错误代码,
不起任何作用.

XML语法规则要求严格的第二表现---大小写敏感---这也是在语法规则上与html不同的地方.元素
名称必须区分大小写(元素闭合代码要与元素本身大小写一致).

e.g: 下面两行代码,第一行是错误的,第二行是正确的
<p>我的故事是什么呢?</P>
~~~~
<p>我的故事是什么呢?</p>
XML语法规则要求严格的第三表现---嵌套对应

---我们在html代码中经常见到这样的例子
html: <b><i>呵呵,真的管理不严哟</b></i>
然而在XML代码中,则拒绝上述代码书写规格,所有的元素必须一一对应
XML: <b><i>哇赛,真的好严格哟</i></b>

当我们声明一个XML文件的同时,我们必须建立一个根元素标记,就如同一篇文章的标题一样.所有
的XML代码都要有根元素
e.g:

<?xml version="1.0" encoding="GB2312"?>
<我的故事> ----根元素,任何完整的XML代码必须包含此元素
............. ----子元素内容,以"<xxx>",</xxx>形式描述
</我的故事>

XML语法规则严格的表现第五:"懒惰等于慢性自杀"

还记得'"'双引号么?在我们编写html的时候,往往会忽略掉引号,有时候即使知道.但懒惰的天
性总是让我们不愿正确的去输入...因果相报,以前的坏习惯到了编写XML的时候变成了最可怕的噩
梦....一旦忽略了引号..我们会陷入烦恼的境界,尤其是在用于描述庞大复杂的数据的时候...引
号的修改会累垮你的(这里有自动整理数据为XML的软件,但我不打算现在推荐,怕好心办坏事呀,养
成好习惯很重要--别恨我)....而且当我们xml元素含有属性值得时候,这个属性值也必须被引号包


e.g:
<?xml version="1.0" encoding="GB2312"?>----这行引号要是少了就不是XML文件了^^
<我的故事 价值="无价之宝"> ---如果属性值失去双引号,则出现错误
.................
</我的故事>

XML语法规则严格的表现第六:"空白真的是虚无么?"

记不得谁说的了"空既是无",我甚至一度为此痴迷,差点出家...可是当我遇到了XML....我的思
想不得不改变了(空并非无),我的每一个空格都会单独的蹦出来就好像隐形人一样,看不见,却占着
空间.也不知道这是不是严格的规则^_^


今天的课程到此结束,请期待后续课程,希望各位网友安排好学习时间^_^


--------------------------------------------------------------------------------

XML元素与XML属性值

XML元素是可扩展的.也就意味着XML文档内容可以随时通过扩展来储存更多的数据信息.
 

e.g:

<?xml version="1.0"encoding="GB2312"?>
<龙虾大餐>
<价格>枪毙你的工资</价格>
<口感>一斑斑</口感>
<副作用>闹肚子</副作用>
</龙虾大餐>

  这时,如果我们要通过我们的应用程序或其他的东西来输出这段数据的部分内容,如<价格>,
<口感>,<副作用>.将会现实如下结果(输出结果因你的输出形式确定,xml数据内容本身不做改
变)

e.g:

关于龙虾大餐
价格:枪毙你的工资
口感:一斑斑
副作用:闹肚子
欢迎您品尝 (此例子为假想例子,除数据内容为实外其他皆为假想,请不要搞乱你的头绪)

  当输出后我们忽然发现,还需要向数据中添加新的数据,该怎么办呢?

  很简单,直接夹在XML数据中即可.
e.g:

<?xml version="1.0"encoding="GB2312"?>
<龙虾大餐>
<价格>枪毙你的工资</价格>
<口感>一斑斑</口感>
<副作用>闹肚子</副作用>
<意见>可以用活的龙虾代替么?</意见>
<感想>还是有钱好,起码饭后还有钱付治疗肠胃的医药费
</感想>
</龙虾大餐>

  一定有人会问"这样添加数据会影响到前面的假想例子么?".呵呵,不会!

  在我们添加数据后,上面的假想例子依然输出同样的结果.而且也可以通过改变应用程序来显
示我们新加入的数据.
XML元素间关系,由于XML元素必须规定根元素,所以根元素以下的元素都为子元素,相互为兄弟元素
关系,为了数据存储方便,请确保子元素内容与根元素相关,并且各个兄弟元素间也最好有逻辑上的
关联.

  XML元素内容,一个完整的XML文件由于它的用于储存数据的特性决定它一定要有内容,而它的
内容则是被声明在各个元素之中的,在这里,这个内容可以是空白内容,也可以是简单的文本或单一
数据,也可以复杂的多个数据列,甚至还可以是其他的分类子元素.

  XML元素命名规则,同java,c等命名规则类似,可以是英文字母或中文作为元素名(也可以是其
他语言,但要首先确保你的数据读取软件可以支持),可以用数字和字母作为名字开头,名称中不能
出现空格!!!可以用下划线"_"取代空格的功能来进行详细命名,而且在名称中严禁出现":"号

XML系列教程第三讲-XML属性值


  前面的讲座中曾经出现过元素的属性值.

e.g:

<我的故事 价值="无价之宝">
.........
</我的故事>

  其中价值="无价之宝"这段代码就是根元素"我的故事"的属性值

  那么,属性值可以做什么呢?xml中的属性值可以被用来为元素添加额外的说明信息.其实我们
很早以前就已经接触过属性值,而且频率非常的高,那就是出现在html中的属性值.

e.g:
<font size="7" color="red">属性值在html中的运用</font>
~~~~~~~~ ~~~~~~~~~~~
<a href="http://go.go.go">到处都是属性值的运用</a>

在xml中,我们也可以应用属性值到元素,但不要太频繁,毕竟XML是用来储存和发送数据信息的,因
此它的可扩展性就显得非常重要,我们可能随时需要向xml文件中添加数据,虽然使用属性值可以方
便的为元素添加额外信息说明,但是这样做非常不利于日后的维护和更新...更何况,这些事情使用
元素来做才是正确真正的选择(因此,本人不推荐频繁使用属性值).

e.g:

属性值运用

<?xml version="1.0" encoding="GB2312"?>
<我的介绍 姓名="jsper" 性别="unknow" 职业="无"联系方式="jsper@371.net">
</我的介绍>

不使用属性值

<?xml version="1.0" encoding="GB2312"?>
<我的介绍>
<姓名>jsper</姓名>
<性别>unknow</性别>
<职业>无</职业>
<联系方式>jsper@371.net</联系方式>
</我的介绍>

  显而易见,频繁的使用属性值很难与维护和更新,而且,使用属性值还有一系列的弱点---
1,属性值不可以包含多重数值(元素可以);
2,属性值难于扩展(考虑到长远打算);
3,属性值不能够用于描述结构内容(子元素则可以);
4,属性值很难通过DTD来进行一个测试(关于DTD的介绍,请期待后续教程)

  也许你们的语法老师都告诉过你们这样一句话"是规则就有例外",在这里也同样应验...毕
竟属性值也不是一无是处^_^.我们可以用数值来表示同一元素的不同内容.如下

e.g:
<?xml version="1.0"encoding="GB2312"?>
<通讯薄>
<我的网友 编号="008">
<姓名>飞鸟</姓名>
<性别>未知</性别>
<联系方式>不详</联系方式>
</我的网友>

<我的网友 编号="009">
<姓名>飞鱼</姓名>
<性别>中性</性别>
<联系方式>未知</联系方式>
</我的网友>
</通讯薄>

  在这里,我们用的是数字来区分元素"我的网友",当然你也可以用其他的方式来区分.例如"
编号="一号"


--------------------------------------------------------------------------------

CSS在xml中的应用

已经进行了2讲了...想必一定有很多人等着看我的好戏,呵呵,关于XML的基础知识,我们已经大致
了解了,在进行更高级的课程之前,请允许我稍微改变一下课程安排,以便能够让你们"看"下去(国
内太多枯燥的课程了,很多次我看的头昏眼花想呕吐,不过,他们的语言很精练,很学究^_^,不像我,
罗里罗唆)...所以我临时决定插一道菜进来,那就是---魔法的揭示---CSS在XML中的应用...不是
盖的哟,你的XML数据内容可以直接看了(不是目录树,是真的显示出来哟).
 

  事先声明,正规的用来显示XML数据的方法是使用XSL等技术(下一讲---皇家的术士--XSL在XML
中的应用),这里介绍只是一种通过现有的技术显示XML数据的方法(你不得不承认CSS是广泛存在于
国内的^^).

下面是一段常见的XML代码:
e.g:

<?xml version="1.0" encoding="GB2312"?>
<mywrong>
<reason>有人说我的文章废话连篇</reason>
<question>我真的是废话连篇,罗里罗唆么?</question>
<think>我是不是应该考虑以严谨的,充满学究味道的写作风格继续进行创作? </think>
<request>如果你对我的教程有意见,请一定写信给我Jsper@371.net</request>
</mywrong>

  接下来是一段常见的CSS代码(进行html网页制作的怎么可能不知道?我在此不再阐述)
e.g:

mywrong
{
background-color: #ffffff;
width: 100%;
}

reason
{
font-family : "宋体";
font-size : 22pt;
display: block;
margin-bottom: 10pt;
margin-left: 20;
}

question
{
font-family : "宋体";
font-size : 9pt;
color: red;
}
think
{
font-family : "宋体";
font-size : 9pt;
Display: block;
margin-bottom: 10pt;
color: green;
}

request
{
font-family : "宋体";
font-size :9pt;
Display: block;
color: yellow;
margin-left: 20pt;
}

  在接下来是混合CSS到XML中的代码,仅仅添加一行用以引用CSS文件的代码
e.g:
<?xml version="1.0" encoding="GB2312"?>
★★★ <?xml-stylesheet type="text/css" href="mywrong.txt"?>
<mywrong>
<reason>有人说我的文章废话连篇</reason>
<question>我真的是废话连篇,罗里罗唆么?</question>
<think>我是不是应该考虑以严谨的,充满学究味道的写作风格继续进行创作?</think>
<request>如果你对我的教程有意见,请一定写信给我Jsper@371.net</request>
</mywrong>

  然后请分别将三段代码存为mybackup.xml,mywrong.txt,mywrong.xml之后在浏览器输入
mywrong.xml地址,呵呵,效果出来了吧!


--------------------------------------------------------------------------------

皇家的术士(初涉XSL)

激动人心的时刻到了,听,皇家的号角已经响起,皇家的术士--XSL--出场了!!
 

  讲起xsl(eXtensible StylesheetLanguage),我忍不住又要把html拉出来了(反正它也习惯了
^^),在html中,有许多简单易懂的标记用来显示数据内容,比如我们可以通过<h1>,<fontcolor
>等来设置数据内容的显示格式,而且这些标记通过名称就可以很容易的判断出用途,但是.谁叫它
天生就是用来显示数据信息的呢?不过我们的XML就不能这样了,天生就是用来储存和发送数据信息
的(劳累命呀),所以,不得已只能求助其他的方式来显示数据内容,于是,我们的术士就出现了.

  作为术士,XSL会的东西远比我们前面介绍的CSS强大的多.它由两种方式构成,一种方式用来转
换XML文本内容,另一种则是格式化XML文本内容.我们可以通过XSL首先转换(过滤和整理)XML数据
内容,并通过XSL的格式化显示方法定义数据内容显示方式(比如字体大小,颜色等).

  我们的术士也可以定义一个可以被浏览器支持的用来显示转换后的XML数据的方式,目前来讲,
这种方式往往是转换XML元素为HTML元素.

  同时,XSL也可以加入或者移除一些元素到输出文件(可以理解为魔法的力量^^),也可以重新整
理排列这些元素,并且决定哪些元素将要被显示和如何被显示.

  接下来,是我们的魔法展示,请留心观看:

e.g:

第一部分,一个简单的XML文件:

<?xml version="1.0" encoding="GB2312"?>
<国王的心腹>
<皇家术士>
<姓名>jsper</姓名>
<代号>008</代号>
<性别>unknow</性别>
<地位>术士(不是骗人的巫婆和半仙)</地位>
<爱好>施展internet魔法</爱好>
<附注>
哪位好心人可以提供我一个工作?术士快交不起电话费了
我的信箱是jsper@371.net 我的icq是:12233550
</附注>
<谢谢>真的很感谢你们对我的支持,我会继续努力的
</谢谢>
</皇家术士>
<皇家术士>
<姓名>XSL</姓名>
<代号>001</代号>
<地位>
the eXtensible Stylesheet Language
</地位>
</皇家术士>
</国王的心腹>

请将此代码内容保存为mybackup.xml

第二部分,首次出现的XSL文件:

<?xml version="1.0" encoding="GB2312"?>
<html xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<body style="font-size:12pt;background-color:blue">
<xsl:for-each select="国王的心腹/皇家术士">
<div style="background-color:green;color:white;padding:4px">
<span syle="font-weight:bold;color:white">
姓名:<xsl:value-of select="姓名"/>
</span>
<p>代号:<xsl:value-of select="代号"/></p>
<p>性别:<xsl:value-of select="性别"/></p>
<p>地位:<xsl:value-of select="地位"/></p>
<p>爱好:<xsl:value-of select="爱好"/></p>
</div>
<div style="background-color:yellow;color:red;
font-size:9pt;margin-bottom:10pt;">
<p><center><xsl:value-of select="附注"/></center></p>
</div>
<div style="background-color:orange;color:green;
font-size:9pt;">
<center><xsl:value-of select="谢谢"/></center>
</div>
</xsl:for-each>
</body>
</html>

请将此段代码内容保存为aboutme.xsl
第三部分.混合显示魔法

<?xml version="1.0" encoding="GB2312"?>
<?xml:stylesheet type="text/xsl" href="aboutme.xsl"?>
<国王的心腹>
<皇家术士>
<姓名>jsper</姓名>
<代号>008</代号>
<性别>unknow</性别>
<地位>术士(不是骗人的巫婆和半仙)</地位>
<爱好>施展internet魔法</爱好>
<附注>
哪位好心人可以提供我一个工作?术士快交不起电话费了
我的信箱是jsper@371.net 我的icq是:12233550
</附注>
<谢谢>真的很感谢你们对我的支持,我会继续努力的</谢谢>
</皇家术士>
<皇家术士>
<姓名>XSL</姓名>
<代号>001</代号>
<地位>the eXtensible Stylesheet Language</地位>
</皇家术士>
</国王的心腹>

请将此段代码内容保存为aboutme.xml

  当我们在浏览器中打开aboutme.xml的时候...我们就可以看到神奇的魔法效果了^^

  至此,我们对xsl已经有了初步了解,关于它的深度讲解请期待后续教程,谢谢.


--------------------------------------------------------------------------------

xml中的数据岛

暂时忘记前面的术士,让我们再一次回到xml构造的数据世界,以前我总是爱讲"详细内容请看后面
章节",这次没办法拖了,只好开始讲述"后面章节"的内容,今天所要讲述的是DataIslands(直译
就行了,数据岛).
  我们用数据岛可以做什么呢?,我们可以利用数据岛将我们的XML嵌入到html叶面中,至于怎么
做,就看我接下来的演示好了.

  我们可以通过<xml>(请把这里的<XML>标记看作为html元素)标记来嵌入我们的XML数据.
也可以通过引用来导入一个外部的独立的XML文件.

e.g:

1,内嵌XML数据

<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=gb2312">
<title>第一次亲密接触(非痞子蔡版,请不要理解为侵权)</title>
</head>
<body>
<xml id="第一次亲密接触">
<第一次亲密接触>
<对象>xml</对象>
<亲密程度>接触到XML稍微宝贵的地方---数据岛</亲密程度>
<结论>感觉不错,是个好东东</结论>
</第一次亲密接触>
</xml>
<center><h1>第一次亲密接触</h1></center>
<table border="0" datasrc="#第一次亲密接触" align="center" width="443">
<tr>
<td bgcolor="#99FF99">对象: <span datafld="对象"></span></td>
<td bgcolor="#3399CC">亲密程度:<span datafld="亲密程度"></span></td>
<td bgcolor="#CC99CC">结论: <span datafld="结论"></span></td>
</tr>
</table>
</body>
</html>
e.g:

2.外部xml文件的引用

  首先利用以前的知识建立一个XML文件(不是我懒,给你们一个机会锻炼^^)

  涉及到以下<xml></xml>中的数据内容
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=gb2312">
<title>第一次亲密接触(非痞子蔡版,请不要理解为侵权)</title>
</head>
<body>
<xml id="第一次亲密接触" src="firstlove.xml">
<第一次亲密接触>
<对象>xml</对象>
<亲密程度>接触到XML稍微宝贵的地方数据岛</亲密程度>
<结论>感觉不错,是个好东东</结论>
</第一次亲密接触>
</xml>
<center><h1>第一次亲密接触</h1></center>
<table border="0" datasrc="#第一次亲密接触" align="center">
<tr>
<td bgcolor="#99FF99">对象: <span datafld="对象"></span></td>
<td bgcolor="#3399CC">亲密程度:<span datafld="亲密程度"></span></td>
<td bgcolor="#CC99CC">结论: <span datafld="结论"></span></td>
</tr>
</table>
</body>
</html>

  我们可以通过指定XML文件位置来引用她,一般通过src="XXX.xml"引用.
[/font]
[b][font=tahoma]The future is not set. There is no fate but what we make for ourselves![/b][/font]
级别: 侠客
显示用户信息 
1  发表于: 2002-03-10   
回复:
非常感谢这篇文章。可否对xsl做更进一步的介绍比如说分成xslt和xsl_fo来介绍?
可否将css按css1和css2来介绍?再次感谢了
级别: 圣骑士
显示用户信息 
2  发表于: 2002-03-10   
回复:
说实话……我对XML了解不多……

我会去找点资料……

不过CSS好像可研究的东西不多?

[b][font=tahoma]The future is not set. There is no fate but what we make for ourselves![/b][/font]
级别: 圣骑士
显示用户信息 
3  发表于: 2002-03-10   
XSLT 是什么类型的语言?
[font=verdana]
Michael H. Kay (mhkay@iclway.co.uk)

2001 年 2 月

内容:


什么是 XSLT?
XSLT 的角色
XSLT 作为语言
XSLT 处理器的操作
示例样式表
XSLT 的优点
结束语
参考资料
关于作者
评价本文


XSLT 是什么类型的语言,其用途是什么,为什么要这样设计它?这些问题可以有许多不同的答
案,初学者往往会感到困惑,因为这种语言与他们以前习惯使用的语言之间有很大差别。本文尝
试说明 XSLT。本文并不试图教您编写 XSLT 样式表,它将说明这种语言的起源,它擅长什么,以
及您为什么应该使用它。
我撰写本文的初衷是为一篇关于 Saxon 的技术文章提供必要的背景知识,打算提供在传统 XSLT
处理器中使用的实现技巧内幕,从而帮助用户使其样式表的性能达到最大化。但
developerWorks 的编辑们劝说我:这篇介绍应该吸引更广泛的读者,值得作为 XSLT 语言的独立
说明而单独发表。

什么是 XSLT?
XSLT 语言由万维网联盟 (W3C) 定义,并且该语言的 1.0 版本在 1999 年 11 月 16 日作为“推
荐书”发布(请参阅参考资料)。我已经在拙作 XSLT Programmers' Reference 中提供了全面的
规范和用户指南,因此我不打算在本文中涵盖相同内容。确切地讲,本文的目的只是使读者理解
XSLT 适合大规模事物的哪些位置。

XSLT 的角色
XSLT 的最初目的是将信息内容与 Web 显示分离。如其最初定义那样,HTML 通过按抽象概念(如
段落、重点和编号列表)定义显示来实现设备独立性。随着 Web 变得越来越商业化,出版人希望
其输出质量能达到与印刷品相同的质量。这逐渐导致越来越多地使用具体显示控件,如页面上材
料的明确字体和绝对位置。然而不幸的是完全可以预料其副作用,即将相同的内容传递到替代设
备,如数字电视机和 WAP 电话(印刷业的行话再现效果)将会变得日益困难。

由于吸收了印刷业使用 SGML 的经验,在 1998 年初定义了一种标记语言 XML,它用于表示独立
于显示的结构化内容。与 HTML 使用一组固定概念(如段落、列表和表)不同,XML 标记中使用
的标记完全是用户定义的,其用意是这些标记应该与所关注的对象(如人、地点、价格和日期)
相关。尽管 HTML 中的元素本质上都是印刷样式(虽然处于抽象级别),而 XML 的目标是元素应
该描述实际对象。例如,清单 1 显示了表示足球锦标赛结果的 XML 文档。

清单 1. 表示足球锦标赛结果的 XML 文档
<results group="A">
<match>
<date>10-Jun-1998</date>
<team score="2">Brazil</team>
<team score="1">Scotland</team>
</match>
<match>
<date>10-Jun-1998</date>
<team score="2">Morocco</team>
<team score="2">Norway</team>
</match>
<match>
<date>16-Jun-1998</date>
<team score="1">Scotland</team>
<team score="1">Norway</team>
</match>
<match>
<date>16-Jun-1998</date>
<team score="3">Brazil</team>
<team score="0">Morocco</team>
</match>
<match>
<date>23-Jun-1998</date>
<team score="1">Brazil</team>
<team score="2">Norway</team>
</match>
<match>
<date>23-Jun-1998</date>
<team score="0">Scotland</team>
<team score="3">Morocco</team>
</match>
</results>




如果要通过 Web 浏览器显示这些足球赛的结果,不要指望系统会产生合理的布局。需要其它一些
机制来告诉系统如何在浏览器屏幕、电视机、WAP 电话或真正在纸张上显示数据。这就是使用样
式表的目的。样式表是一组说明性的规则,它定义了应如何表示源文档中标记标识的信息元素。

W3C 已经定义了两个系列的样式表标准。第一个是在 HTML 中广泛使用的 CSS(级联样式表),
当然它也可以在 XML 中使用。例如,可以使用 CSS 来表示何时显示发票,应支付的总额应该用
16 点 Helvetica 粗体字显示。但是,CSS 不能执行计算、重新整理或排序数据、组合多个源码
中的数据或根据用户或会话的特征个性化显示的内容。在这个足球赛结果的例子中,CSS 语言
(即使是最新版本 CSS2,尚未在产品中完全实现)的功能还不够强大,不能处理这项任务。由于
这些原因,W3C 已着手开发更强大的样式表语言 XSL(可扩展样式表语言),并采纳了 SGML 社
区中开发的 DSSSL(文档样式、语义和规范语言)中许多好的构思。

在 XSL 的开发过程中(这在 DSSSL 中已有所预示),发现在准备 XML 文档以备显示的过程中执
行的任务可以分成两个阶段:转换和格式化。转换是将一个 XML 文档(或其内存中的表示法)转
换成另一个 XML 文档的过程。格式是将已转换的树状结构转换成两维图形表示法或可能是一维音
频流的过程。XSLT 是为控制第一阶段“转换”而开发的语言。第二阶段“格式化”的开发工作还
是进行中。但实际上,大多数人现在使用 XSL 将 XML 文档转换成 HTML,并使用 HTML 浏览器作
为格式化引擎。这是可行的,因为 HTML 实际上只是 XML 词汇表的一个示例,而 XSLT 可以使用
任何 XML 词汇表作为其目标。

将转换成一种语言和格式化成另一种语言这两个操作分离经证实的确是一种好的决策,因为转换
语言的许多应用程序经证明无法向用户显示文档。随着 XML 日益广泛地用作电子商务中的数据互
换语法,对于应用程序将数据从一个 XML 词汇表转换成另一个 XML 词汇表的需求也在不断增
加。例如,某个应用程序可能从电视收视指南中抽取电视节目的细节,并将它们插入按次付费客
户的月帐单中。同样,还有许多实用的数据转换,在这些转换中源词汇表和目标词汇表是相同
的。它们包括数据过滤,以及商务操作,如施行涨价。因此,随着在系统中开始越来越多地以
XML 语法的形式使用数据,XSLT 就逐渐成为由于处理这些数据的随处可见的高级语言。

在拙作中,我做了这样一个比喻:XSLT 与 XML 的关系,就好象 SQL 与表格化数据的关系一样。
关系模型的强大功能并非来自用表存储数据的思想,而是源于 SQL 中可行的基于关系运算的高级
数据操作。同样,XML 的层次化数据模型对应用程序开发者的帮助实际上也非常小。正是因为
XSLT 作为 XML 数据的高级操作语言提供了如此强大的功能。

XSLT 作为语言
就某些方面而言,XSLT 作为一种语言来说是非常古怪的。我不打算在本文中讨论已做出的设计决
策的基本原理,尽管可以通过它们在逻辑上追溯到语言设计者确定的对 XSLT 的要求。如需更完
整的说明,请参阅拙作的第 1 章。

以下概述了 XSLT 语言的部分主要特性。

XSLT 样式表是一个 XML 文档。通过使用 XML 的尖括号标记语法来表示文档的结构。这种语法在
某种程度上是比较笨拙的,而此决策可以使该语言变得更罗嗦。但是,它确实有好处。它表示可
以自动使用 XML 的所有词汇设备(例如,Unicode 字符编码和转义,使用外部实体等等)。它表
示很容易使 XSLT 样式表变成转换的输入或输出,使该语言可以作用于自身。它还使将期望的
XML 输出块嵌入样式表变得很容易。实际上,许多简单的样式表基本上可以写作期望输出文档的
模板,并且可以将一些特殊指令嵌入文本中,以便插入输入中的变量数据或计算某个值。这就使
XSLT 在这个简单的级别上非常类似于许多现有的专用 HTML 模板语言。

基本处理范例是模式匹配。在这方面,XSLT 继承了文本处理语言(如 Perl)的传统,这种传统
可以一直追溯到 1960 年代的语言,如 SNOBOL。XSLT 样式表包括一组模板规则,每条规则都使
用以下方式:“如果在输入中遇到此条件,则生成下列输出。”规则的顺序是无关紧要的,当有
几条规则匹配同一个输入时,将应用冲突解决算法。然而,XSLT 与串行文本处理语言的不同之处
是 XSLT 对输入并非逐行进行处理。实际上,XSLT 将输入 XML 文档视为树状结构,每条模板规
则都适用于树中的一个节点。模板规则本身可以决定下一步处理哪些节点,因此不必按输入文档
的原始顺序来扫描输入。

XSLT 处理器的操作
XSLT 处理器使用树状结构作为其输入,并生成另一个树状结构作为输出。图 1 中显示了这一
点。

图 1. XSLT 输入和输出的树状结构


常常通过对 XML 文档进行语法分析来生成输入树状结构,而输出树状结构通常被串行化到另一
个 XML 文档中。但 XSLT 处理器本身操作的是树状结构,而不是 XML 字符流。这个概念最初给
许多用户的感觉是不切实际的,结果却对理解如何执行更复杂的转换起了关键作用。首先,它表
示 XSLT 处理器可以理解源文档中与树状结构无关的特殊之处。例如,无论属性是包括在单引号
中还是在双引号中,都不可能应用不同的处理,因为会将这两种形式视为同一个基本文档的不同
表示方法。更深入地看,它表示处理输入元素或生成输出元素是一个原子操作。不可能将处理元
素的开始标记和结束标记分成单独的操作,因为一个元素会自动表示成树模型的单节点。

XSLT 使用叫作 XPath 的子语言来引用输入树中的节点。XPath 本质上是与具有层次结构的 XML
数据模型相匹配的查询语言。它可以通过按任何方向浏览树来选择节点,并根据节点的值和位置
应用谓词。它还包括用于基本字符串处理、数字计算和布尔代数的工具。例如,XPath 表达
式 ../@title 选择当前节点的父代元素的标题属性。XPath 表达式用于选择要进行处理的输入节
点、在条件处理期间测试条件,以及计算值以便插入结果树中。模板规则中还使用了 XPath 表达
式的简化形式“模式”来定义特定模板规则适用于哪些节点。XPath 在单独的 W3C 推荐书中定
义,它允许使用在其它上下文中再使用的查询语言,特别是用于定义扩展超链接的 XPointer。

XSLT 以传统语言(如 Lisp、Haskell 和 Scheme)中的功能性编程的概念为基础。样式表由模板
组成,这些模板基本上是单一功能 -- 每个模板将输出树的一部分定义成一部分输入树的功能,
并且不产生副作用。使用无副作用的规则受到严格控制(除了转义成用类似 Java 的语言编写的
外部代码)。XSLT 语言允许定义变量,但不允许现有变量更改它的值 -- 即没有赋值语句。这个
策略使许多新用户感到困惑,其目的是为了允许逐步应用样式表。其原理是如果语言没有副作
用,那么对输入文档做很小的改动时,不必从头执行整个转换就应该可以计算出对输出文档的最
后更改。目前必须说这只是理论上的可能,任何现有 XSLT 处理器还不能实现。(注:虽然
XSLT 以功能性编程概念为基础,但它还不是一个完整的功能性编程语言,因为它缺少将函数当作
一级数据类型进行处理的能力。)

示例样式表
在这个阶段,使用示例会使语言变得更清楚。清单 2 显示了列出足球赛结果的简单样式表。

清单 2. 足球赛结果的基本样式表

<xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="results">
<html>
<head><title>
Results of Group <xsl:value-of select="@group">
</title></head>
<body><h1>
Results of Group <xsl:value-of select="@group">
</h1>
<xsl:apply-templates>
</body></html>
</xsl:template>

<xsl:template match="match">
<h2>
<xsl:value-of select="team[1]"> versus <xsl:value-of select="team[2]">
</h2>
<p>Played on <xsl:value-of select="date"></p>
<p>Result:
<xsl:value-of select="team[1] ">
<xsl:value-of select="team[1]/@score">,
<xsl:value-of select="team[2] ">
<xsl:value-of select="team[2]/@score">
</p>
</xsl:template>

</xsl:transform>





这个样式表包括两个模板规则,一个匹配 <results> 元素,另一个匹配 <match> 元素。
<results> 元素的模板规则输出页面的标题,然后调用 <xsl:apply-templates>,这是一个
XSLT 指令,它将处理当前元素的所有子代,对于每个子代都使用其适当的模板规则。在本例中,
<results> 元素的所有子代都是 <match> 元素,所以会用第二个模板规则来处理它们。规则输出
了一个标识比赛的次级 HTML 标题(以 "Brazil versus Scotland" 的形式),然后生成 HTML
段落,给出了比赛的日期和两队的比分。

该转换的结果就是一个 HTML 文档,该文档在浏览器中的表示如图 2 所示。

图 2. 清单 2 中样式表的结果


这是一种非常简单的表示信息的方法。然而,XSLT 的功能比这要强大得多。清单 3 包含了另一
个可以操作相同源数据的样式表。这次,样式表计算一个比赛名次表,用来显示锦标赛结束时各
队的名次。

清单3. 计算球队名次表的样式表
<xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">


<xsl:variable name="teams" select="//team[not(.=preceding::team)]">
<xsl:variable name="matches" select="//match">

<xsl:template match="results">

<html><body>
<h1>Results of Group <xsl:value-of select="@group"></h1>

<table cellpadding="5">
<tr>
<td>Team</td>
<td>Played</td>
<td>Won</td>
<td>Drawn</td>
<td>Lost</td>
<td>For</td>
<td>Against</td>
</tr>
<xsl:for-each select="$teams">
<xsl:variable name="this" select=".">
<xsl:variable name="played" select="count($matches[team=$this])">

<xsl:variable name="won"
select="count($matches[team[.=$this]/@score > team[.!=$this]/@score])">
<xsl:variable name="lost"
select="count($matches[team[.=$this]/@score < team[.!=$this]/@score])">
<xsl:variable name="drawn"
select="count($matches[team[.=$this]/@score = team[.!=$this]/@score])">
<xsl:variable name="for"
select="sum($matches/team[.=current()]/@score)">
<xsl:variable name="against"
select="sum($matches[team=current()]/team/@score) - $for">

<tr>
<td><xsl:value-of select="."></td>
<td><xsl:value-of select="$played"></td>
<td><xsl:value-of select="$won"></td>
<td><xsl:value-of select="$drawn"></td>
<td><xsl:value-of select="$lost"></td>
<td><xsl:value-of select="$for"></td>
<td><xsl:value-of select="$against"></td>
</tr>
</xsl:for-each>
</table>
</body></html>
</xsl:template>

</xsl:transform>





这里没有足够的篇幅来完整地说明这个样式表,简而言之,它为球队声明了一个变量,变量值是
一个节点集合,其中每个参赛球队都有一个实例。然后它计算每支球队的胜、平或负的比赛场次
总数,以及球队进球或失球的总数。图 3 显示了它在浏览器中的最终输出结果。



图 3. 清单 3 中名次样式表的结果


这个示例的目的是说明 XSLT 不单单能够对源文档中出现的文本指定字体和布局。它是一个完整
的编程语言,能够以任何方式转换源数据以供显示,或者输入另一个应用程序。

XSLT 的优点
您为什么考虑使用 XSLT?

XSLT 给了您传统高级声明编程语言的所有好处,特别是对于转换 XML 文档的任务。

高级语言带来的实际好处是开发生产力。但实际上,真正的价值源自于更改的潜力。与使用低级
DOM 和 SAX 接口编码的过程性应用程序相比,用于转换 XML 数据结构的 XSLT 应用程序更能适
应对 XML 文档细节的更改。在数据库世界中,这种特性叫做数据独立性,正是由于数据独立性导
致了诸如 SQL 之类声明性语言的成功,并使旧的引导性数据访问语言走向衰亡。我坚信在 XML
世界中也会这样。

当然与所有声明性语言一样,XSLT 也会降低性能。但是对于大多数应用程序,今天的 XSLT 处理
器的性能已经完全能够满足应用程序的需要,并且它会变得越来越好。在我的第二篇文章中,我
将讨论 XSLT 处理器中使用的一些优化技巧,如我自己的 Saxon 产品。

结束语
我想要在本文中展示的是 XSLT 是一种用于操作 XML 文档的完整高级语言,就如同 SQL 是操作
关系表的高级语言一样。应该注意到 XSLT 不仅是一种样式设计语言,它比 CSS(或者甚至
CSS2)的功能更强大。

我见到过一些应用程序,它们的所有商务逻辑都用 XSLT 编码。在一个三层在线银行系统中,我
看到:


从后端操作系统以 XML 消息的形式检索所有数据。
在联机会话的持续时间内,用户的帐户数据在内存中以 XML DOM 形式表示。
所有给用户的信息首先封装成 XML 消息,然后用服务器或客户机附带的 XSLT 转换根据浏览器的
性能将这些消息转换成 HTML。

该应用程序的数据都是 XML 格式的,并且逻辑(包括数据访问逻辑、商务逻辑和显示逻辑)都
由 XSLT 来实现。我建议每个项目都采用那种体系结构,但这还需要很长时间,我认为我们会在
几年之内见到那种系统。

作为一种编程语言,XSLT 有许多特性 -- 从它使用 XML 语法到其功能性编程原理的基础 -- 还
不为一般 Web 程序员所熟悉。那意味着一条陡峭的学习曲线和通常遇到许多挫折。当初对于
SQL 也是如此,所有这些表示 XSLT 与以前的编程语言有着本质的区别。但不要放弃:它是功能
非常强大的技术,值得努力学习。

参考资料

同一个作者撰写的 Wrox 书籍 XSLT Programmer's Reference。XSLT 语言的综合指南。
W3C 出版的 XSLT 1.0 Recommendation。XSLT 语言的权威性规范。
W3C 出版的 XPath 1.0 Recommendation。XSLT 样式表中使用的 XPath 表达式语法的权威性规
范。
XSL-List,一个有关 XSLT 所有事物的繁忙邮件列表,它附带有可搜索档案,由 MulberryTech
进行管理。
www.xslinfo.com,一个很好的网络中央页面,带有到 XSLT 资源的链接,内容包括软件、书籍、
教程和其它内容。
关于作者
Michael Kay 在 XML 界非常著名,他是 Saxon XSLT 处理器和 Wrox 书籍 XSLT Programmer's
Reference 的作者。多年以前,他就获得了博士学位,他的研究领域是数据库技术。自那时起,
他设计了 Codasyl 数据库、关系数据库、面向对象数据库和自由文本数据库软件。

在写作时,Michael 还兼了几份工作(并没有休息)。他刚结束了在 ICL(一家英国 IT 服务公
司)24 年的工作,并投奔 Software AG 成为体系结构小组的一员,该小组负责掌控未来 XML 产
品的方向。
[/font]
[b][font=tahoma]The future is not set. There is no fate but what we make for ourselves![/b][/font]
级别: 圣骑士
显示用户信息 
4  发表于: 2002-03-10   
回复:
[url]http://www-900.ibm.com/developerWorks/xml/x-xslt/index.shtml[/url]
[b][font=tahoma]The future is not set. There is no fate but what we make for ourselves![/b][/font]
描述
快速回复

按"Ctrl+Enter"直接提交