级别: 初级
IBM, 作者
2003 年 3 月 01 日
对于一批XML数据,应用处理程序要综合XML文档、文档类型说明(Dtd/Schema) 以及样式单三方面要素来处理和显示它。
什么是样式单
对于一批XML数据,应用处理程序要综合XML文档、文档类型说明(Dtd/Schema)
以及样式单三方面要素来处理和显示它。
在XML文档中只包含了数据信息,并没有涉及文档如何显示。不错,制定XML标准的
目的是要使数据结构化,赋予其明确的语意,使之易于进行数据交换。XML早已不再
把目光局限在文字图象的显示上,而是要建立它们之间的内在关系。可以说,XML文
档本身是重内容而不重形式。
可是,XML结构化地组织信息固然好,但如果不加修饰地把一大堆枯燥的数据摆在那里,也足以令人眼花头痛。
样式单(StyleSheet)是一种专门描述结构文档表现方式的文档,它既可以描述这些
文档如何在屏幕上显示,也可以描述它们的打印效果,甚至声音效果。样式单一般不
包含在XML文档内部,而以独立的文档方式存在。
样式单可以实现非常复杂的显示效果,但由于样式描述与数据描述相分离,显示细节
的描述并不影响文档中数据的内在结构。
样式单的最大优点是:XML关于文档浏览的基本思想是将数据与数据的显示分别定义。
这样一来,XML格式文档不会重蹈某些HTML文档结构混杂、内容繁乱的覆辙,XML的
编写者也可以集中精力于数据本身,而不受显示方式的细枝末节的影响。不仅如此,
样式单还带来另一个好处,即定义不同的样式表可以使相同的数据呈现出不同的显示
外观,从而适合于不同应用,甚至能够在不同的显示设备上显示。这样,XML数据就
可以得到最大程度上的重用性,满足不同的应用需求。
XSLT
W3C已经给出了两种样式单语言的推荐标准,一种是层叠样式单CSS(Cascading
Style Sheets),另一种是可扩展样式单语言XSL(eXtensible Stylesheet
Language)。本章讲的是XSL。
XSL本身就是一个XML文档,它是通过XML进行定义的,遵守XML的语法规则,是XML
的一种具体应用。因此系统可以使用同一个XML解释器对XML文档及其相关的XSL文
档进行解释处理。XSL由两大部分组成:第一部分描述了如何将一个XML文档进行转
换,转换为可浏览或可输出的格式;第二部分则定义了格式对象FO(fomatted
object)。由于到目前为止,W3C还未能出台一个得到多方认可的FO,因此本章主
要XML变换--XSL transformations(XSLT)。现在一般所说的XSL大都指的
是XSLT。
XSLT的应用
XSLT主要的功能就是转换,它将一个没有形式表现的XML内容文档作为一个源树,
将其转换为一个有样式信息的结果树。在XSLT文档中定义了与XML文档中各个逻辑
成分相匹配的模板,以及匹配转换方式。它可以很好地描述XML文档向任何一个其
它格式的文档作转换的方法,例如转换为另一个逻辑结构的XML文档、HTML文档、
XHTML文档、VRML文档、SVG文档等等,不一而足。
使用XSL定义XML文档显示方式的基本思想是:通过定义转换模板,将XML源文档
转换为带样式信息的可浏览文档。
限于目前浏览器的支持能力,大多数情况下是转换为一个HTML文档进行显示。
在XML中声明XSL样式单的方法为:<?xml-stylesheet type="text/xsl" href="mystyle.xsl"?>
至于具体的转换过程,既可以在服务器端进行,也可以在客户端进行。
XSLT样式单文档举例
下面是一个具体的xslt样式单文档:
<?xml version="1.0" encoding="gb2312" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/tr/WD-xsl"> <xsl:template match="/"> <HTML> <HEAD> <TITLE>学生花名册</TITLE> <STYLE> .title{font-size:15pt; font-weight:bold; color:blue } .name{color:red} </STYLE> </HEAD> <BODY> <P class="title" >学生花名册</P> <xsl:apply-templates select="学生花名册"/> </BODY> </HTML> </xsl:template>
<xsl:template match="学生花名册"> <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="学生" order-by="名字"> <tr> <td><B><xsl:value-of select="名字"/></B></td> <td><xsl:value-of select="籍贯"/></td> <td><xsl:value-of select="年龄"/></td> <td><xsl:value-of select = "电话号码"/></td> </tr> </xsl:for-each> </table> </xsl:template> </xsl:stylesheet>
|
模板在XSLT中的应用
将上例的XML文档用XSL样式转换为HTML文档的步骤是:先用XML解释器将XML文档
解释成DOM对象,相当于建立了原文档的一个节点树。然后用XML解释器解释XSL文
档,用模板匹配的方法去遍历XML节点树,将树中的节点按模板的设定转换为模板指
示的显示语言,即HTML语言。
要了解这段程序,就要先了解模板。xsl:template是模板元素,用于定义模板,通
常每个xsl:template有一个节点匹配属性,由"match="指定。在对模板进行匹配时
使用"xsl:apply-templates",用"select"属性选择要匹配的模板,相当于一个
调用的过程。比如在
<xsl:apply-templates select="学生花名册"/>
这段语句中用到了xsl:apply-templates,于是系统就跳到了用<xsl:template
match="学生花名册">括起的“函数”中生成HTML代码。
如果在xsl:apply-templates语句中没有指定select属性,那么就调用所有可以调
用的模板。
接着介绍xslt常用的几条语句。
- 介绍一下XSL的几条主要语句:
- xsl:stylesheet 声明语句
- xsl:for-each select = "" 循环语句,遍历与引号中的属性值相同的节点
- xsl:value-of select = "" 赋值语句,取出引号中指定的属性值
分析XSLT代码执行过程
在作过XML声明和XSL声明之后,系统最先匹配XML源树的根节点。根节点用"/"表
示,它的匹配方法在一对<xsl:template match="/">括起的源码中声明。按照
这段代码,首先生成带有样式信息的HTML文档的开头一段代码:
<HTML> <HEAD> <TITLE>学生花名册</TITLE> <STYLE> .title{font-size:15pt; font-weight:bold; color:blue } .name{color:red} </STYLE> </HEAD> <BODY> <P class="title" >学生花名册</P>
|
接着,系统看到了<xsl:apply-templates select="学生花名册"/>的指示,于是,
它在XML源树中寻找标记为“学生花名册”的节点进行匹配。就象函数调用一样,现在系
统跳到了用<xsl:template match="学生花名册">括起的“函数”中继续生成下面的
HTML代码:
<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="学生" order-by="名字">。
这条指示要求系统寻找标记为“student”的子节点,并按照“名字”下的内容将这些节
点排序,然后一一处理。
对于每一个“学生”子树中的内容,系统为其生成表中一行的内容。每一行包含四列,
分别把标记为“名字”、“籍贯”、“年龄”、“电话号码”的子节点的内容填进去。
其中“名字”下的内容还是粗体显示。对应到本例中的XML数据,生成的HTML代码为:
<tr> <td><B>李华</B></td> <td>河北</td> <td>15</td> <td>62875555</td> </tr> <tr> <td><B>张三</B></td> <td>北京</td> <td>14</td> <td>82873425</td> </tr>
|
处理完<xsl:for-each select="学生" order-by="名字">中的内容,系统继续生成HTML代码:
至此,系统已处理完<xsl:template match="学生花名册">中的所有内容,可以“函数
返回”了。
系统返回到<xsl:template match="/">括起的源码中,完成HTML最后两行代码的生成:
把上面的HTML代码串起来,就是生成的转换结果文件。
XSLT文件文档结构
前面说过,XSLT文档本身是XML文档,因此文档的第一句自然是:
<?xml version="1.0" encoding="gb2312"?>
|
接下来是样式单部分:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/tr/WD-xsl"> ... ... </xsl:stylesheet>
|
xmlns:xsl指示了XSL的命名空间,在XSLT标准中,定义了XSLT的命名空间为
http://www.w3.org/1999/XSL/transform,然而在ie5中不支持这个名字
空间,需要用到微软自己的名字空间http://www.w3.org/tr/WD-xsl。
XSLT在进行转换时,首先遍历XML源文档树,找到要处理的节点,然后将定义好
的模板信息施加到该节点中。
下面将要介绍xslt样式单的语法。
样式单模板xsl:template
xsl:template元素有一个mode属性,可以根据需要去匹配不同模式的模板。
若将前例作如下修改:
<xsl:template match="/" mode="blue"> ... <TITLE>学生花名册</TITLE> <STYLE> .title{font-size:15pt; font-weight:bold; color:blue } ... <xsl:template match="/" mode="red"> ... <TITLE>学生花名册</TITLE> <STYLE> .title{font-size:15pt; font-weight:bold; color:red }
|
如果要将TITLE输出为蓝色,则用下面语句匹配:
<xsl:apply-templates select="/" mode="blue"/>
如果要将title输出为红色,则写为:
<xsl:apply-templates select="/" mode="red"/>
此外,模板总是与节点相对应的,一个节点可能对应于不同的模板,那么如何确定各
模板匹配的先后次序呢?XSLT中可为xsl:template设置优先级,写法是:
<xsl:template match="student" priority="n"> //n为优先级数
xsl:value-of计算节点值
在使用XSLT进行转换时,常常需要获取节点值,使用xsl:value-of元素可达到
这个目的,如下例:
<xsl:value-of select="籍贯"/>
得到的是学生原籍的值,select属性指定要获取的是哪一个节点的节点值。
xsl:for-each循环处理
使用xsl:for-each可对所选节点依次进行处理,如例中在生成表格处理中,就是
利用循环将各个学生的信息取出放入表格中的,写法是:
<xsl:for-each select="student" order-by="name"> ... </xsl:for-each>
|
可以认为<xsl:for-each select="">能实现多个
<xsl:apply-templates select="">的功能。
xsl:sort排序处理
对于用xsl:for-each或xsl:apply-templates匹配的节点,可使用xsl:sort将
所选节点内容进行排序
- 按大小写排序
<xsl:sort case-order="upper-first" select="@id"/>
以id为关键字按大写优先排序
<xsl:sort case-order="lower-first" select="@id"/>
以id为关键字按小写优先排序
- 按字母顺序排序
<xsl:sort order="ascending" select="@id "/>
以id为关键字按字母升序排序
<xsl:sort order="descending" select="@id "/>
以id为关键字按字母降序排序
- 按数据类型排序
<xsl:sort data-type="text" select="@id"/>
以id为关键字按文本类型排序,如对于一组id数据101,2,44,305
来说,排序结果是101,2,305,44
<xsl:sort data-type="number" select="@id"/>
以id为关键字按数据类型排序,上面一组数据的排序结果是2,44,101,305
另外,还有一种指定排序的方法,就是在前面学生花名册例中所使用的order-by:
<xsl:for-each select="student" order-by="name">
也可使得输出学生时按名字排序。
元素与属性创建
XSLT是一个动态的样式单,在处理过程中可产生新的元素或元素属性,方法如下:
内 容 |
元 素 |
举 例 |
转换结果 |
创建元素 |
xsl:element |
<xsl:element name="TITLE">学生花名册</xsl:element> |
学生花名册 |
创建属性 |
xsl: attribute |
<TITLE><xsl:attribute name="style">color:blue </xsl:attribute>学生花名册</TITLE > |
<TITLE style="color:blue">学生花名册</TITLE> |
创建文本 |
xsl:text (可以保护文本中的空白字符) |
<xsl:text> 这是学生花名册 </xsl:text > |
这是学生花名册 |
创建处理指令 |
xsl:processing-instruction |
<xsl:processing-instruction name="xml-stylesheet"> href="book.css" type="text/css" </xsl:processing-instruction> |
<?xml-stylesheet href="book.css" type="text/css"?> |
创建注释 |
xsl:comment |
<xsl:comment> 以下是学生花名册,请勿删改! </xsl:comment> |
<!-- 以下是学生花名册,请勿删改!--> |
节点拷贝
在对XML文档进行处理时,XSLT还可以通过拷贝的方式复制节点,方法是利用
xsl:copy和xsl:copy-of。其中xsl:copy只拷贝当前节点,不包括子节
点和属性;而xsl:copy-of的拷贝内容则包括当前节点、子节点和属性。
例如对于:
<p id="p1">A <B>is a char</B> </p>
如果样式单写为如下形式:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/transform"> <xsl:template match="p"> <DIV> <xsl:text> copy-of : </xsl:text> <xsl:copy-of select="."/> </DIV> <DIV> <xsl:text> copy : </xsl:text> <xsl:copy/> </DIV> </xsl:template> </xsl:stylesheet>
|
转换后生成如下代码:
<DIV> copy-of : <p id="p1">A <B>is a char</B> </p> </DIV> <DIV> copy : <p/> </DIV>
|
由此可见,两种拷贝方式结果大相径庭。
输出格式与编码问题
XSLT是一个转换语言,它的目的是将XML源文档转换为另一种格式文档,它的输出结
果可以是HTML文档,也可以是带CSS的XML文档。具体的输出格式由xsl:output 指
定。如果要输出为HTML文档,则写为:
<xsl:output method="html"/>
同样,要输出XML文档写为:
<xsl:output method="xml"/>
如果文档中不出现xsl:output,将缺省输出为XML文档,但如果在匹配模板时使用了
<HTML>标记,则输出为HTML文档。输出为HTML文档时系统都会自动加上下面语句:
<!DOCTYPE html PUBLIC "-//W3C//Dtd HTML 4.0 transitional//EN">
此外,还可以利用xsl:output指定编码方式,如UTF-8,UTF-16,GB2312等。例如:
<xsl:output method="html" encoding="GB2312"/>
它指定了该XSLT的输出结果是HTML格式,编码方式为中文。
关于作者
|
|
|
IBM has authored this article
|