分类: 系统运维
2006-08-09 15:24:12
自从 1999 年 11 月面世以来,我发现 XSLT(XSL 转换语言)是可用于操作 XML 文档的最有用的工具之一。许多可用的 API 和工具在 Java 或其他语言中使用 XML 文档,而且我在不同项目中使用了许多 XML 文档,但想不起有哪个 XML 项目不使用一点 XSLT 了。
那 么我对 XSLT 2.0 开发有浓厚的兴趣就不足为奇了。XSLT 是功能强大的语言,它高级到甚至可以处理最复杂的操作,但它也非常冗长,以至于调试和维护大型样式表非常困难。W3C 希望解决这个问题和其他问题,所以将要发布两种语言:XSLT 2.0 和 XQuery 1.0。本文对这两种即将面世的语言进行比较,并提供了一些有关如何有效利用这两种语言的指导。
在撰写本文时,XSLT 2.0 和 XQuery 1.0 还处于 Candidate Release 状态,该状态是 W3C 用于不久要采用的标准的行话。多久?这取决于审查过程。
在设计上,XSLT 2.0 和 XQuery 1.0 有许多共同点。两种语言都基于同一基础:XPath 2.0。两种语言都专用于操作 XML 文档。两种语言都借用脚本 概念,即对简单任务使用解释语言。实际上,可以使用其中任一语言达到给定目的。两者功能相当。但是,每种语言都有不同的个性,我觉得,取决于要进行的任务,也可能取决于您的个性,您可能会更喜欢使用其中的一个,所以两个都值得学习一下。
下文将简单介绍两种语言的共同点和各自的特点,以便您选择适合自己的风格和正在进行的任务的一种语言。
首先介绍 XPath 2.0。XSLT 由两种语言打包而成:XPath 语言和 XSLT 本身。XPath 是用于查询元素的语言,例如,选择属性或指定模板匹配(XSLT 中的匹配属性)时。XSLT 语言是用于指定转换结果的语言,指令包括 xsl:apply-templates
、xsl:value-of
和 xsl:for-each
等。
考虑 清单 1 中的 XSLT 模板。它混合了一些 XPath 语言(match
和 select
属性)、来自 XSLT 本身的元素(模板和 xsl:value-of
指令)和来自结果语言的元素(html
和 head
):
|
XPath 和 XSLT 之间的任务分离并不新奇,但因为没有其他语言是基于 XPath 的,因此在 XQuery 出现以前,二者主要是理论区别。
XPath 2.0 是非常重要的升级。XPath 1.0 只能查询 XML 文档中的节点。XPath 2.0 可以操作序列,而序列可以包含节点(所以不会丢失任何内容)以及字符串、整数和其他原子值。差别虽细小但很重要:现在可以通过第二次查询提炼查询结果。以 前在 XSLT 1.0 中,链接两个查询需要专用的功能。
另一个重要的更改是 XPath 2.0 支持循环和变量。换句话说,您可以在 XPath 中声明变量并从 XPath 中为其赋值。同样地对于循环,您可以在 XPath 中运行循环以计算返回值,例如,在处理发票行时用数量乘以价值。仍可以在 XSLT 中声明变量,XSLT 中的循环功能也有所增强。在升级中包装了许多强大功能!
新选项极大地简化了 XSLT 样式表。在 XSLT 1.0 中,必须编写许多算法,甚至递归编写简单算法。例如,计算发票总计时通常都需要递归算法。但在 XSLT 2.0 中再也不必如此了,这大大归功于 XPath 2.0 中的新功能。
|
XSLT 样式表可用于任何 XML 操作。就我个人而言,我曾使用 XSLT 进行网站发布、编译报告、计算统计、预处理 XML 文件,转换不同词汇或软件、准备导入数据库中的数据、处理数据库导出,甚至响应 Web 服务请求。
实际上,这是滥用语言。当然它能工作,但有时候最终的结果是与语言对抗。得到的样式表有太多递归函数,难以调试。
顾名思义,问题在于 XSLT 设计用于转换文档以发布,而非其他目的。XSLT 旨在作为一种通用查询语言,尽管它总是在没有更好选择的情况下被使用。与此相反,XQuery 设计用于查询文档和准备报告。
不可否认,转换 和查询 是涵盖许多应用的通用词。已经介绍过,两种语言能力相当,因为它们都基于 XPath 2.0。但它们强调不同的用法模式,从而使其适用于不同的任务。
XSLT 的设计者假设您有意于处理大部分文档,这种假设在发布时是合理的。因此 XSLT 具有内置的遍历引擎,在默认情况下会处理整个文档。他们还假设您通常使用文本信息,因此 XSLT 不是一种强类型语言,最后,他们还假设您将以标记语言生成文档,因此 XSLT 编写为 XML 词汇。
XQuery 的设计者作了不同的假设。他们假设您在运行查询时希望将范围缩小到文档的一些章节,所以他们围绕 XPath 查询构建该语言。XQuery 没有默认行为,一切由您主宰。
他们还假设您使用有类型的数据,比如数据库抽象,而 XQuery 是强类型语言。最后,语法绝对不是 XML。
|
为了阐明 XSLT 2.0 和 XQuery 1.0 之间的差异,我们来看一个示例。
为 了比较两种语言,人们通常用两种语言编写同一个算法,但在特殊情况下,这样并不公平。因为每种语言都是在其他语言表现不佳的任务中表现良好,所以使用一个 示例将给出有偏颇的结果。所以我决定使用两个示例:一个转换示例用于 XSLT,一个查询示例用于 XQuery。通过比较,将会发现为什么这些语言适用于不同的需要。
两个示例都在 清单 2 上运行,清单 2 是 RSS 中的文章列表。
|
清单 3 是 XSLT 样式表。它用 HTML 发布 RSS 文档。该样式表包含 清单 2 中每个元素的模板 (xsl:template),它依赖 XSLT 处理器选择最适合的模板。可以看到,样式表假设您将处理整个文档。XSLT 还将很好地处理混合元素。
|
注意声明方法:您指定如何处理元素,处理器(通过其内置的树遍历逻辑)决定何时应用模板。添加和移除模板很容易。代码不包含循环,因为处理器已经知道如何遍历文档。
清单 4 是 XQuery 示例。它运行两个查询:一个用于提取星期五发布的文章列表,一个用于列出讨论 XMI 的文章。
|
比较 清单 4 和 清单 3。在 XQuery 中,代码依赖于 XPath 直接指向感兴趣的元素,且循环必须显式编写。从文档中提取报告时,它十分理想。
|
我开始使用 XSLT 2.0 和 XQuery 1.0 作为 XPath 2.0 的不同语支。每种语支适用于特定的应用程序。只有时间能说明这两种语支是否都将茁壮成长。就目前来看,我打算专注于 XPath 2.0,并根据要开发的应用程序使用最适合的语支。