XSLT 是什么类型的语言? |
| ||||
Michael H. Kay XSLT是什么类型的语言,其用途是什么,为什么要这样设计它?这些问题可以有许多不同的答案,初学者往往会感到困惑,因为这种语言与他们以前习惯使用的语言之间有很大差别。本文尝试说明XSLT。本文并不试图教您编写 XSLT样式表,它将说明这种语言的起源,它擅长什么,以及您为什么应该使用它。 我撰写本文的初衷是为一篇关于 Saxon 的技术文章提供必要的背景知识,打算提供在传统 XSLT 处理器中使用的实现技巧内幕,从而帮助用户使其样式表的性能达到最大化。但 developerWorks 的编辑们劝说我:这篇介绍应该吸引更广泛的读者,值得作为 XSLT 语言的独立说明而单独发表。 什么是 XSLT? XSLT 的角色 由于吸收了印刷业使用 SGML 的经验,在 1998 年初定义了一种标记语言 XML,它用于表示独立于显示的结构化内容。与 HTML 使用一组固定概念(如段落、列表和表)不同,XML 标记中使用的标记完全是用户定义的,其用意是这些标记应该与所关注的对象(如人、地点、价格和日期)相关。尽管 HTML 中的元素本质上都是印刷样式(虽然处于抽象级别),而 XML 的目标是元素应该描述实际对象。例如,清单 1 显示了表示足球锦标赛结果的 XML 文档。 清单 1. 表示足球锦标赛结果的 XML 文档
如果要通过 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 样式表是一个 XML 文档 。通过使用 XML 的尖括号标记语法来表示文档的结构。这种语法在某种程度上是比较笨拙的,而此决策可以使该语言变得更罗嗦。但是,它确实有好处。它表示可以自动使用 XML 的所有词汇设备(例如,Unicode 字符编码和转义,使用外部实体等等)。它表示很容易使 XSLT 样式表变成转换的输入或输出,使该语言可以作用于自身。它还使将期望的 XML 输出块嵌入样式表变得很容易。实际上,许多简单的样式表基本上可以写作期望输出文档的模板,并且可以将一些特殊指令嵌入文本中,以便插入输入中的变量数据或计算某个值。这就使 XSLT 在这个简单的级别上非常类似于许多现有的专用 HTML 模板语言。 基本处理范例是模式匹配。 在这方面,XSLT 继承了文本处理语言(如 Perl)的传统,这种传统可以一直追溯到 1960 年代的语言,如 SNOBOL。XSLT 样式表包括一组模板规则,每条规则都使用以下方式:“如果在输入中遇到此条件,则生成下列输出。”规则的顺序是无关紧要的,当有几条规则匹配同一个输入时,将应用冲突解决算法。然而,XSLT 与串行文本处理语言的不同之处是 XSLT 对输入并非逐行进行处理。实际上,XSLT 将输入 XML 文档视为树状结构,每条模板规则都适用于树中的一个节点。模板规则本身可以决定下一步处理哪些节点,因此不必按输入文档的原始顺序来扫描输入。 XSLT 处理器的操作 常常通过对 XML 文档进行语法分析来生成输入树状结构,而输出树状结构通常被串行化到另一个 XML 文档中。但 XSLT 处理器本身操作的是树状结构,而不是 XML 字符流。这个概念最初给许多用户的感觉是不切实际的,结果却对理解如何执行更复杂的转换起了关键作用。首先,它表示 XSLT 处理器可以理解源文档中与树状结构无关的特殊之处。例如,无论属性是包括在单引号中还是在双引号中,都不可能应用不同的处理,因为会将这两种形式视为同一个基本文档的不同表示方法。更深入地看,它表示处理输入元素或生成输出元素是一个原子操作。不可能将处理元素的开始标记和结束标记分成单独的操作,因为一个元素会自动表示成树模型的单节点。 XSLT 使用叫作 XPath 的子语言来引用输入树中的节点。XPath 本质上是与具有层次结构的 XML 数据模型相匹配的查询语言。它可以通过按任何方向浏览树来选择节点,并根据节点的值和位置应用谓词。它还包括用于基本字符串处理、数字计算和布尔代数的工具。例如,XPath 表达式 XSLT 以传统语言(如 Lisp、Haskell 和 Scheme)中的功能性编程的概念为基础。样式表由模板组成,这些模板基本上是单一功能 -- 每个模板将输出树的一部分定义成一部分输入树的功能,并且不产生副作用。使用无副作用的规则受到严格控制(除了转义成用类似 Java 的语言编写的外部代码)。XSLT 语言允许定义变量,但不允许现有变量更改它的值 -- 即没有赋值语句。这个策略使许多新用户感到困惑,其目的是为了允许逐步应用样式表。其原理是如果语言没有副作用,那么对输入文档做很小的改动时,不必从头执行整个转换就应该可以计算出对输出文档的最后更改。目前必须说这只是理论上的可能,任何现有 XSLT 处理器还不能实现。(注:虽然 XSLT 以功能性编程概念为基础,但它还不是一个完整的功能性编程语言,因为它缺少将函数当作一级数据类型进行处理的能力。) 示例样式表
这个样式表包括两个模板规则,一个匹配 该转换的结果就是一个 HTML 文档,该文档在浏览器中的表示如图 2 所示。 这是一种非常简单的表示信息的方法。然而,XSLT 的功能比这要强大得多。清单 3 包含了另一个可以操作相同源数据的样式表。这次,样式表计算一个比赛名次表,用来显示锦标赛结束时各队的名次。 清单3. 计算球队名次表的样式表
这里没有足够的篇幅来完整地说明这个样式表,简而言之,它为球队声明了一个变量,变量值是一个节点集合,其中每个参赛球队都有一个实例。然后它计算每支球队的胜、平或负的比赛场次总数,以及球队进球或失球的总数。图 3 显示了它在浏览器中的最终输出结果。 这个示例的目的是说明 XSLT 不单单能够对源文档中出现的文本指定字体和布局。它是一个完整的编程语言,能够以任何方式转换源数据以供显示,或者输入另一个应用程序。 XSLT 的优点 XSLT 给了您传统高级声明编程语言的所有好处,特别是对于转换 XML 文档的任务。 高级语言带来的实际好处是开发生产力。但实际上,真正的价值源自于 更改的潜力 。与使用低级 DOM 和 SAX 接口编码的过程性应用程序相比,用于转换 XML 数据结构的 XSLT 应用程序更能适应对 XML 文档细节的更改。在数据库世界中,这种特性叫做 数据独立性 ,正是由于数据独立性导致了诸如 SQL 之类声明性语言的成功,并使旧的引导性数据访问语言走向衰亡。我坚信在 XML 世界中也会这样。 当然与所有声明性语言一样,XSLT 也会降低性能。但是对于大多数应用程序,今天的 XSLT 处理器的性能已经完全能够满足应用程序的需要,并且它会变得越来越好。在我的第二篇文章中,我将讨论 XSLT 处理器中使用的一些优化技巧,如我自己的 Saxon 产品。 结束语 我见到过一些应用程序,它们的所有商务逻辑都用 XSLT 编码。在一个三层在线银行系统中,我看到:
该应用程序的数据都是 XML 格式的,并且逻辑(包括数据访问逻辑、商务逻辑和显示逻辑)都由 XSLT 来实现。我建议每个项目都采用那种体系结构,但这还需要很长时间,我认为我们会在几年之内见到那种系统。 作为一种编程语言,XSLT 有许多特性 -- 从它使用 XML 语法到其功能性编程原理的基础 -- 还不为一般 Web 程序员所熟悉。那意味着一条陡峭的学习曲线和通常遇到许多挫折。当初对于 SQL 也是如此,所有这些表示 XSLT 与以前的编程语言有着本质的区别。但不要放弃:它是功能非常强大的技术,值得努力学习。
|