22 August 2005
中级
您可能还记得我在上一篇文章 XML 概述中提到过,XML 专门用于承载数据。但是,大部分 Web 应用程序在设计时都要考虑最终用户。因此,信息必须以可读的格式呈现。这就是 XSL 的用途所在:它从 XML 树获取数据并对数据进行处理,最后生成智能输出。当然,您可以采用自己的方式使用 Perl、Java 或 PHP 来转换 XML 文档。但是,随着 XML 逐渐成为主流,您必须很好地掌握 XSL 及其工作原理。
幸运地是,Dreamweaver 8 采用了一种可视化的方法来进行 XSL 转换,从而使您完全不需要手动编码即可处理基于 XML 的数据。为了理解如何能够将 XML 和 XSL 结合使用以处理和显示信息,本文介绍了 XSL 及其一些实际应用。本文的涵盖了基本的 XSL 语法规则,列举了一些如何使用 XSL 设置数据样式的示例,并解释了服务器端和客户端转换的差异。
XSL 之于 XML 就像 CSS 之于 HTML。它是指可扩展样式表语言 EXtensible Stylesheet Language 。这是一种用于以可读格式呈现 XML 数据的语言。XSL 实际上包含两个部分:
XSLT 是指 XSL 转换 XSL Transformation ,它是 XSL 最重要的部分。
XSLT 可以将 XML 文档转换为其它 XML 文档、XHTML 输出或简单的文本。这通常是通过将每个 XML 元素转换为 HTML 元素来完成的。由于 XML 标签是用户定义的,浏览器不知道如何解释或呈现每个标签,因此必须使用 XSL。XML 标签的意义是为了方便用户(而不是计算机)理解。
XSLT 还可以对 XML 树进行下列操作:
如果您需要回顾 XML 语法,请阅读我以前关于 XML 的文章的“XML 语法”部分。
您可能还记得 XML 概述文章中提到过,所有 XML 文档都是以 XML 声明开头。XSL 样式表也是一样。任何 XSL 文档的第一行实际上都是 XML 声明:
<?xml version="1.0" encoding="ISO-8859-1"?>
既是又不是。说是,是因为它们遵循相同的语法规则(只有少许差异,下面我将会讲到)。说不是,是因为它们的用途不同:XML 用于承载数据,而 XSL 则用于设置数据的格式。
在 XML 声明之后,就是 XSL 声明,例如:
<xsl:stylesheet>
或
<xsl:transform>
但是,在大多数实际情况下,XSL 声明看起来要稍微复杂一些:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
这是因为,根据 W3C 联盟的建议,它还包含命名空间和 XSL 规范的版本。
XSL 声明与 XML 声明的不同之处在于,XML 声明只写一行,而且没有结束标签,而 XSL 声明必须包含结束标签,该标签表示 XSL 样式表结束:
</xsl:stylesheet>
请注意,这并不与 XML 语法规则冲突:XSL 样式表是完全有效的 XML 文档,因为它有一个根元素,由 <xsl:stylesheet> 标签指定。
XSL 在设计时有几个目标用途,这些用途使它成为某些开发情况下的完美解决方案,而对另一些开发情况则毫无用处。
XSL 如何发挥作用?要为网站的访问者生成最终的 HTML 页,需要对 XML 数据源应用 XSL 样式表。实际的转换可以由 Web 服务器或客户端浏览器来执行。最终的输出可以是完整的 HTML 页,或者只是用于单独页上的一部分。
服务器端和客户端方法都有各自的优缺点。服务器端转换使您可以处理服务器或 Internet 其它位置上的 XML 文档。服务器执行实际工作,生成任何浏览器(无论是旧版本还是新版本)都可载入的 HTML 输出。另一方面,要执行服务器端 XSL 转换,必须正确配置应用程序服务器,使其支持 XML 和 XSL。不是所有的承载服务器都具备这种支持能力。因此,我将在以后的文章中介绍如何为 PHP 服务器安装和配置所需的 XML/XSL 库。即将发布的 Dreamweaver 8 支持对 ColdFusion、ASP、ASP.NET 和 PHP 页执行 XSL 转换。
服务器端转换工作流程如下图所示:
请注意,XML 文档不必位于 Web 服务器上。它也可以放置在远程网站上,这样,在需要它时可以将其载入服务器。
在客户端转换中,所有的工作都由客户端的浏览器执行。此方法的缺点在于,并非所有的浏览器都支持 XML/XSL,因此某些客户端可能无法看到您的页面。要获得具有 XML/XSL 功能的现代浏览器的列表,请访问 W3C 联盟网站上的此页面。另外,在使用客户端方法时,您只能处理本地 XML 文件。例如,如果需要收集其它网站的 RSS 源,就必须下载它的一个副本,然后上载到您的服务器上。如果远程网站上的原始 RSS 文件发生更改,则必须重新下载该文件,然后重新张贴到您的 Web 服务器上。
为了向浏览器指明必须使用哪个 XSL 样式表来处理该 XML 文档,必须在 XML 文件中紧随 XML 声明之后包含如下声明:
<?xml-stylesheet type="text/xsl" href="company.xsl"?>
href 属性指定必须使用的 XSL 样式表的路径。这种机制类似于在 HTML 页的开头引用外部 CSS 样式表的方法。下图显示了客户端 XSL 转换的工作流程:
我以前提到过,XSL 声明还承载文档的命名空间。按照字面意思解释,命名空间就是名称的空间。它指定一组可以在特定文档中使用的元素名称和属性名称。命名空间的作用是避免命名冲突。由于 XML 和其它与 XML 相关的语言都是用户定义的,所以可能出现命名冲突。例如,<table> 可能是指一个数据库表、一个布局表、一件家具或是饭店的一个座位。由于大多数应用程序同时处理多个 XML 文档,因此经常会有不同 XML 文档相混合的情况,而在这些文档中某个元素可能代表不同的含义。几个文档使用相同的命名空间可以确保元素在每个文档中代表相同含义。否则,就应该使用不同的命名空间确保元素代表不同的含义。
在 XML 中,命名空间由文档声明中的 xmlns 属性指定。它们包含 URI(统一资源标识符),即网站的地址(例如 http://www.w3.org/1999/XSL/Transform)。其基本原理是 URI 具有唯一性,因此很可能相应的命名空间也是唯一的。
备注:文档声明中的 URI 仅用作名称。而不是指向任何 XML 架构的链接或文档所有者(最初发布文档的公司或网站)的指示。
既然您已经对命名空间有所了解,那么我们就回到 XSL 语法上。就像 XML 文档是由分层的元素集合构成一样,XSL 文档是由模板或规则构成的。每个模板定义应用于特定 XML 节点的规则。XSL 模板如下所示:
<xsl:template match="">
</xsl:template>
match 属性将 XSL 模板与 XML 元素相关联。相应的节点由 XPath 表达式来表示。我将在下一部分中介绍 XPath。
XSL 使用 XPath 来标识 XML 树中需要处理的各个元素。简而言之,XPath 是用于定位 XML 元素的导航工具。它使用的语法与操作系统中文件系统路径的语法相同(例如 C:\Program Files\Macromedia\,或 /usr/bin/perl)。与此类似,XPath 表达式 company/department/employee 指向包含有关一个公司及其部门数据的 XML 文档中的 employee 元素。Dreamweaver 8 提供可视化的拖放用户界面,并可以为您创建 XPath 语句,但是您仍应该了解 XPath 的基本原理,以便能够在 XSL 样式表中控制 XML 数据。
XPath 规范基本上遵循与文件系统寻址相同的规则:
//employee 会查找 XML 文档中的所有员工节点。/company/department/* 选择一个部门的所有子节点,即该部门的所有员工。../employee。@ 字符。例如,/company/department/employee[@retired] 选择指定了 retired 属性的所有员工。<xsl:template> 元素的内容是必须应用的实际规则。它通常是一些可以输出到浏览器的 HTML 代码。
还记得我以前的文章中的 company.xml 文档吗?假设您需要向员工节点应用一个规则,以便在如下图所示的表中显示员工:
XSL 规则如下所示:
<xsl:template match="/">
<table border="1">
<tr>
<th>Name</th>
<th>Job</th>
<th>Salary</th>
</tr>
</table>
</xsl:template>
请注意,table 标签中的内容是纯 HTML 代码。它会告知浏览器,以表的形式显示员工,并且使用以下列标题:Name、Job 和 Salary。
<xsl:template> 用于定义节点在浏览器中的显示方式。但是,为了显示节点的实际内容,需要使用另一种 XSL 构造:<xsl:value-of>。它的名称是相当直观的。要显示的值的节点由 select 属性指定,该属性的值由 XPath 表达式确定。假设您需要显示 company.xml 文档中的某个员工的姓名。代码应该如下所示:
<xsl:value-of select="/company/department/employee/name"/>
回顾前一个示例,我们曾以表的形式显示 company.xml 文档;为按照已定义的 XSL 模板显示 <name>、<job> 和 <salary> 节点的值,需要编写如下代码:
<xsl:template match="/">
<table boder="1">
<tr>
<th>Name</th>
<th>Job</th>
<th>Salary</th>
</tr>
<tr>
<td><xsl:value-of select="company/department/employee/name"/></td>
<td><xsl:value-of select="company/department/employee/job"/></td>
<td><xsl:value-of select="company/department/employee/salary"/></td>
</tr>
</table>
</xsl:template>
要使该代码能够用于您的浏览器,请完成下面的步骤:
<?xml version="1.0" encoding="iso-8859-1"?><?xml-stylesheet type="text/xsl" href="ex_01.xsl"?>
备注:在本文前面的客户端转换部分中曾提到过此代码。它指示浏览器必须使用哪个 XSL 样式表来处理该 XML 文档。href 属性指定必须使用的 XSL 样式表的路径。
要以表的形式显示所有员工,必须使用另一种常用的 XSL 构造:
<xsl:for-each select=""> </xsl:for-each>
select 属性的值是一个 XPath 表达式,用于指定必须显示的节点组。如果您熟悉其它编程语言,就可以明白,<xsl:for-each> 构造与典型的 for 循环作用相同。
让我们显示该公司的所有员工:
<xsl:template match="/">
<table border="1">
<tr>
<th>Name</th>
<th>Job</th>
<th>Salary</th>
</tr>
<xsl:for-each select="company/department/employee">
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="job"/></td>
<td><xsl:value-of select="salary"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
请注意,name、job 和 salary 的 XPath 表达式为何不需要包括父节点或从文档根开始。这是因为这些元素的路径是根据 <xsl:for-each> 构造中的 XPath 表达式来计算的。要使该代码能够用于您的浏览器,请再次打开 company.xml 文件,并将 href 属性值更改为 ex_02.xsl。然后即可在浏览器中进行预览。您应该看到下面的 HTML 表:
XSL 使您可以对项目进行过滤和排序,并根据条件显示内容。
使用 <xsl:for-each> 构造,您还可以根据条件过滤输出。假设您只想显示雇员中的程序员。
<xsl:template match="/">
<table border="1">
<tr>
<th>Name</th>
<th>Job</th>
<th>Salary</th>
</tr>
<xsl:for-each select="company/department/employee[job='Programmer']">
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="job"/></td>
<td><xsl:value-of select="salary"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
要使该代码能够用于您的浏览器,请再次打开 company.xml 文件,并将 href 属性值更改为 ex_03.xsl。然后即可在浏览器中进行预览。请注意,HTML 表中将只列出 company.xml 文档中作为程序员的员工:
要定义 XML 节点的条件,可以使用下列任何运算符:
可以将项目按字母顺序排列。只需使用 <xsl:sort /> 构造,并指定按哪个节点进行排序。<xsl:sort /> 元素必须嵌套在 <xsl:for-each> 元素中,以确保应用程序可以循环通过所有的项目。使用下面的代码可以按字母顺序显示员工:
<xsl:template match="/">
<table border="1">
<tr>
<th>Name</th>
<th>Job</th>
<th>Salary</th>
</tr>
<xsl:for-each select="company/department/employee">
<xsl:sort select="name" />
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="job"/></td>
<td><xsl:value-of select="salary"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
请注意,sort 元素没有相应的结束标签。要使该代码能够用于您的浏览器,请再次打开 company.xml 文件,并将 href 属性值更改为 ex_04.xsl。然后即可在浏览器中进行预览。请注意,在 HTML 表中,company.xml 文档中的所有员工都将按字母顺序排列:
当然,您只需在 <xsl:sort /> 元素中额外添加一个属性,即可方便地在升序和降序排列顺序之间切换:
<xsl:sort select="/name" order="descending"/>
请注意,上面的 XSL 代码不会修改初始 XML 文档的实际结构。执行 XSL 转换之后,在所生成的发送到浏览器的 HTML 中,员工是按照字母顺序列出的。
在大多数语言中,XSL 还能够根据条件显示内容。
单一条件是使用下面的语法定义的:
<xsl:if test="expression">
</xsl:if>
要对多个项目运行条件测试,以便只显示满足该条件的项目,需要将 xsl:if 构造嵌套在 xsl:for-each 元素中。下面的示例显示了如何只列出薪金高于 2700 元的员工:
<xsl:template match="/">
<table border="1">
<tr>
<th>Name</th>
<th>Job</th>
<th>Salary</th>
</tr>
<xsl:for-each select="company/department/employee">
<xsl:if test="salary > 2700">
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="job"/></td>
<td><xsl:value-of select="salary"/></td>
</tr>
</xsl:if>
</xsl:for-each>
</table>
</xsl:template>
请注意,小于 (<) 和大于 (>) 符号由它们相应的 HTML 转义序列(< 和 >)代替。否则,它们很容易与标签的开头和结尾混淆。要使该代码能够用于您的浏览器,请再次打开 company.xml 文件,并将 href 属性值更改为 ex_05.xsl。然后即可在浏览器中进行预览。请注意,HTML 表中将只列出 company.xml 文档中薪金高于 2700 元的员工:
在测试表达式中可以使用常用的条件运算符:
如果需要将某个值与某个字符串进行比较,则要将字符串放在单引号中(例如 <xsl:if test="job = 'Software Analyst'">)。
象大多数编程语言中的 IF-ELSE 构造一样,您还可以定义更复杂的条件。所使用的语法一看就能明白:
<xsl:choose>
<xsl:when test="expression">
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
为了在多个 XML 节点上测试条件,<xsl:choose> 构造必须嵌套在 <xsl:for-each> 循环中。
假设您要以绿色高亮显示薪金低于 2700 元的所有员工,以蓝色高亮显示薪金高于 2700 元的所有员工:
<xsl:template match="/">
<table border="1">
<tr>
<th>Name</th>
<th>Job</th>
<th>Salary</th>
</tr>
<xsl:for-each select="company/department/employee">
<xsl:choose>
<xsl:when test="salary > 2700">
<tr bgcolor="#66CCFF">
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="job"/></td>
<td><xsl:value-of select="salary"/></td>
</tr>
</xsl:when>
<xsl:otherwise>
<tr bgcolor="#00CC99">
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="job"/></td>
<td><xsl:value-of select="salary"/></td>
</tr>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</table>
</xsl:template>
<xsl:otherwise> 元素指定的是当 XML 节点不满足初始测试条件时默认应用的规则。
要使该代码能够用于您的浏览器,请再次打开 company.xml 文件,并将 href 属性值更改为 ex_06.xsl。然后即可在浏览器中进行预览。您应该看到下面的 HTML 表:
请注意,薪金低于 2700 元的员工将以绿色高亮显示,而薪金高于 2700 元的员工将以蓝色高亮显示。
通过添加一个或多个 <xsl:when> 元素,可以方便地扩展 <xsl:choose> 构造,从而测试多个条件。无论有多少个 <xsl:when> 元素,<xsl:otherwise> 元素只能有一个,用于处理未包括在初始测试条件中的所有其它情况。作为练习,请尝试使用下面的高亮显示方式来显示员工列表:
Dreamweaver 8 的新功能之一是代码提示,它使编码工作变得更快更轻松。当您开始键入 <xsl: 时Dreamweaver 会显示一个列表,给出完成代码输入的建议选项:
要选择所需的节点或函数,请选择它然后按 Enter 键 Windows 或 Return 键 Macintosh 。您可以使用箭头键滚动建议选项的列表。代码提示功能可以帮助您在编写或编辑代码时不出错。
在本文中,我简要介绍了 XSL,并提供了一些在 Web 开发项目中应当何时以及如何使用 XSL 的指导信息。本文还提前介绍了 Dreamweaver 8 中的一些 XML 创作功能,您将发现 Dreamweaver 8 是一个非常有价值的开发工具,非常适用于开发基于 XML 的应用程序。XML 和 XSL 带来了无限的可能,请尽情探索,享受其中的乐趣。
在我的下两篇文章中,我将介绍如何使用 Dreamweaver 8 在您的站点中收集 RSS 源,以及如何配置您的服务器以执行服务器端 XSL 转换。Dreamweaver 8 已经可以预订。如果您通过 Macromedia Affiliate Program from InterAKT Online 订购,您还将获得 免费的 ImpAKT。
Tutorials and samples |
Dreamweaver user forum |
More |
| 02/09/2012 | How to Remove White Space? |
|---|---|
| 09/10/2010 | How to disable some HTML and CSS property's |
| 02/10/2012 |
Difficult to place tag... Please help!
|
| 02/10/2012 | Photo Gallery for mobile devices |
Dreamweaver Cookbook |
More |