《第八章XSL转换XML.ppt》由会员分享,可在线阅读,更多相关《第八章XSL转换XML.ppt(118页珍藏版)》请在三一办公上搜索。
1、第八章 XSL转换XML,第八章 XSL转换XML,8.1 概述 8.2 一个XSL文档的讨论 8.3 XSL样式表 8.4 模板规则 8.5 样式表设计,8.1 概述,本章讨论XML文档的另一种转换技术XSL(XML stylesheet language-XML样式表语言)。W3C在推出XML 1.0规范后,便开始开发符合XML规范要求的转换技术,这就是XSL。XSL包含两个部分:一个是XSLT(XSL Transformation),另一个是定义格式的XML词表。XSL定义一个XML文档的样式,这个定义用XSLT描写XML文档是如何转换成另一个使用格式化词表的XML文档的。,8.1 概述
2、,1999年11月16日,W3C发布了XSLT 1.0。在2001年12月20日发布了XSLT 2.0,之后相继推出7个修订版。XSLT2.0规范包含:样式表结构,数据模型,XSLT语言,模式,模版规则等内容。本书的XSLT以2.0规范作为蓝本进行讨,8.2 一个XSL文档的讨论,在例2.1中我们给出了一个XML文档,现在着手设计一个简单的XSL转换文档来进行转换,在后续的章节逐步深入展开讨论。例8.1 根据例2.1的XML文档,设计一个简单的XSL文件进行转换。图8.1 例2.1 XML文档的树型结构 分析:在例2.1的XML文档中根元素是booklist,在bookist下有若干个book
3、子元素,book下有name、author、press、pubdate、price五个子元素和一个属性isbn。文档的结构如图8.1示。用XSL格式化该XML文档,设计要求为:,8.2 一个XSL文档的讨论,为根元素建立容器,容纳其所有的子元素。每个book显示在屏幕的一个行区域。每个book的子元素显示成一个单元。我们可以为例2.1设计一个XSL(文件名:ch8-1.xsl):123 4 5 图书信息6 7 8 图书信息,8.2 一个XSL文档的讨论,9 10 11 12 13 14 16 15 17 18 19 20,8.2 一个XSL文档的讨论,程序说明:XSL程序是符合XML规范的文档
4、,所以,第1行是该文档为XML文档的声明。第2行的声明此文件是XSL的表单文件,其中的version声明该文档的版本号,xmlns:xsl属性给出此XSL表单文件的名称空间。该声明需要结束符关闭(20行)。3-19行是一个整体,用 定义一个模板,其中的属性match=“/”用来选择该模板从根元素开始构建一个容器。,8.2 一个XSL文档的讨论,4-18行,借助HTML来显示XML元素内容。9-15行使用了循环命令,其中的属性select用来筛选出显示的元素,这是一个XPath表达式。作用是组织循环,显示booklist下的所有book元素。10-14行使用取值命令取出个元素的值,其中的sele
5、ct用来筛选某个具体的元素值。为了显示成一行,使用HTML的段落标记元素来划分段落。每一个元素值后用顿号“、”分隔。当设计好上述的XSL文档后,在例2.1的第二行加上:,8.2 一个XSL文档的讨论,然后在浏览器上显示结果如图8.2所示。,图8.2 用ch8-1.xsl转换ch2-1.xml,8.2 一个XSL文档的讨论,1.什么是XSLT 以样式表(stylesheet)的形式来表示XML文档,把XML文档的元素用特定转换命令实现转换,这就是XSLT。在转换XML源文档时,XSLT的任务是把样式信息添加给一个XML源文件,并把它转换成包含XSL格式化对象的文档,如HTML、XHTML等。样式
6、表就是这个转换技术的核心之一。在XSLT中使用一种叫转换表达式的东西,来描述把源文档树转换成结果树的方法和语法规则。这个转换表达式的规则由XPath规范定义,有关XPath的内容请参考第5章。,8.2 一个XSL文档的讨论,文档树的结构用数据模型说明。转换由一组模版规则来实现。模版(template)把树的层次结构构成的元素序列与模式(pattern)相联系,模式与源文档的结点值匹配。许多情况下,计算这个元素序列会产生新结点作为结果树的一部分。结果树与源树的结构可能相同,也可能完全不同。在构造结果树的过程中,源树的结点可能被过滤掉或被重新排序,还可能加上其他任意结构。这个机制允许样式表能够应用
7、到各种用途的文档,这些文档具有类似源树结构的构造形态。一般情况下,样式表包含的元素可以是用XSLT定义的,也可以不是。当样式表包含的元素是用XSLT定义时,必须使,8.2 一个XSL文档的讨论,用XSLT的名称空间间来进行限定。XSLT的名称空间规定为:http:/www.w3.org/1999/XSL/Transform。例如,在例8.1中xsl文件的第2行,我们使用了这个URI,来规定在整个文件中的XSLT元素都使用XSLT的这个名称空间。2.样式表 样式表是用xsl:stylesheet元素或xsl:transform元素定义的一个整体,由一个以上的模块组成。每一个模块形成一个XML文档
8、的整体或某个部分。每个样式表模块的形成由数据模型中的一个元素结点来表现。样式表模块分为标准和简化两种。,8.2 一个XSL文档的讨论,3.模版规则 XSLT技术以“模板驱动”的方式访问XML数据,通过引进模板来访问XML数据元素及其属性。模版规则定义一个处理容器,这个处理能够用于匹配特定模式的结点。一个模版由一个带xsl:template声明来定义。一个xsl:template元素必须具有一个match或name属性,或两者都有。如果一个xsl:template元素带有match属性,它就是一个模版规则。如果一个xsl:template元素带有name属性,它就是命名模版。,8.2 一个XSL
9、文档的讨论,模版的引用有许多方法,这要根据它是模版规则、还是命名模版来决定。引用模版的结果就是计算包含在xsl:template元素中的序列构造的结果。,8.3.1 样式表元素,1.定义样式表 在XSL中,样式表元素用xsl:stylesheet 和xsl:transform来表示。xsl:stylesheet是一个表示样式表模块的XML元素,xsl:transform是xsl:stylesheet的同义词,所以说这两个元素是等价的。它们的语法格式的简化形式分别为:,8.3.1 样式表元素,如例8.1中的XSL文件中的第2行:就是一个样式表定义。这行代码告诉XSLT解析器现在执行的是一个XSL
10、转换样式表文件。2.样式表子元素 在一个样式表中,可以使用在xsl:stylesheet元素之下的子元素叫顶层元素。常用的顶层元素有:xsl:template、xsl:import、xsl:include、xsl:function、xsl:output、xsl:param、xsl:variable。,8.3.1 样式表元素,3.简化样式表模块 一个简化样式表是一个只包含文档结点的单个模版规则。这个样式表模块可以仅包含文字结果元素和它的内容。简化样式表规则使用匹配模式“/”。例8.2 使用简化样式表规则设计样式表。仍然用例8.1中使用的XML文档来讨论,下面是设计模块:,8.3.1 样式表元素,
11、图书信息新书:因为我们在此简化样式表中,没有使用循环指令,所以只能显示第一本书的名称。,8.3.1 样式表元素,其显示效果如图8.2。,作为一个简化样式表模块最外层元素的文字结果元素,必须具有xsl:version属性,用来指明XSLT的版本。这个版本值正常取2.0。,图8.3 一个简化样式表,8.3.1 样式表元素,4.向前和向后兼容处理 因为XSLT 1.0是1999年发布的,这个1.0版本存在许多弱点,如计算一个求和、平均值这样的问题,必须借助脚本语言来实现,计算功能很弱;格式化信息不丰富等。在后来的2.0版本中采取了废弃一些指令元素的办法,对1.0作了相当大的修改、完善,根本上改变了原
12、来1.0版本的面貌。现在讨论的几乎是一个全新XSLT版本。所谓的向前和向后兼容就是针对XSLT 2.0以前的版本设置的兼容技术,当一个元素的version属性值小于2.0时,我们说它具有向后兼容行为。当大于2.0时说它具有向前兼容行为。,8.3.1 样式表元素,向后兼容时处理器自动使用XSLT1.0来处理XSLT文档。向前兼容的处理器自动使用XSLT2.05.标准属性 为了说明标准属性,我们来参考xsl:styleshee元素的详细格式:,8.3.1 样式表元素,8.3.1 样式表元素,其中出现的属性extension-element-prefixes、exclude-result-prefi
13、xes、version、xpath-default-namespace、default-collation等,就是标准属性。这些标准属性可能出现在所有的XSLT 元素中。version、xpath-default-namespace、default-collation几种属性,其属性值可以被出现在后继元素中的相同属性覆盖。因为这些属性通常只用在xsl:stylesheet元素中,它们对整个样式表下的子模块都有效。8.XSLT的媒体类型 XSLT使用的媒体类型是:application/xslt+xml。,8.3.2 样式表名称空间,关于名称空间的讨论,在2.3节曾经详细讨论过。在XSLT引入名
14、称空间也是出于类似的考虑,因为XSLT技术是面向应用的,当出现许多不同应用具有相同元素和属性名称时,需要把它们分别开来,给应用程序提供分辨属于不同名称空间的元素和属性的可能,这在XSLT的应用中十分重要。XSLT处理器必须使用XML名称空间机制来识别元素和属性。来自XSLT名称空间的元素只在样式表中被识别,而不是在XML源文档中,它的名称空间与源XML的名称空间不能混淆。实现工具也不能扩展具有附加元素和属性的XSLT的名称空间。,8.3.2 样式表名称空间,1.保留名称空间 XSLT名称空间和其它被XSLT处理器识别的某些名称空间,称为保留名称空间,必须只能在XSLT中使用。这些保留的名称空间
15、是:XSLT名称空间:http:/www.w3.org/1999/XSL/Transform 标准函数名称空间:http:/www.w3.org/2005/02/xpath-functions 用来定义函数。XML名称空间:http:/www.w3.org/XML/1998/namespace用于xml:lang和 xml:space属性。,8.3.2 样式表名称空间,模式名称空间:http:/www.w3.org/2001/XMLSchema,用于定义XML 模式。在样式表中,这个名称空间用来引用内置的模式数据类型,以及用这些数据类型构造函数。Xpath数据类型名称空间:http:/www.
16、w3.org/2005/02/xpath-datatypes,用于定义函数和运算符。模式实例名称空间:http:/www.w3.org/2001/XMLSchema-instance,用于定义XML Schema。,8.3.2 样式表名称空间,2.名称空间前缀 名称空间前缀用来定义一个使用的元素与一个名称空间的关联,通常叫做绑定。如例8.1中第2行的xmlns:xsl=http:/www.w3.org/1999/XSL/Transform,就把XSLT的名称空间绑定给前缀xsl。当然XSLT可以使用任意字符串作为名称空间前缀,只要它绑定给规定的XSLT名称空间即可。,8.3.3 样式表模块组合
17、,当一个样式表中需要对若干个XML进行转换的XSL文件时,或对同一个XML需要多种样式表模块来转换时,可以使用包含机制和输入机制。包含机制不改变组合模块的语义来组合样式表模块。输入机制允许样式表彼此覆盖。在XSLT中,包含机制和输入机制用xsl:include和xsl:import来完成。1.样式表包含 包含一个样式表模块,可以使用xsl:include声明,格式为:,8.3.3 样式表模块组合,2.样式表导入 导入一个样式表模块,可以使用xsl:import声明,格式为:xsl:import声明与xsl:include一样,要求具有href属性,它的含义与xsl:include一样。这个元素
18、必须是顶层元素。xsl:import元素的孩子必须先于xsl:stylesheet元素的所有其它元素的孩子,包含任何的xsl:include元素孩子和任何的用户定义数据元素。,8.3.3 样式表模块组合,例8.3 使用xsl:import导入样式表模块。,8.4 模板规则8.4.1模板,1.定义模板 一个xsl:template声明定义一个模版,它包含创建结点和原子值的序列构造。模版既可以作为模版规则,用比照一个模式来匹配结点的方法构造规则,也可以是命名模版,用名称来明确指定。有时,一个模版可以同时具有这两种能力。模版定义的简化规则如下:,8.4.1 模板,说明:match属性标识模版是一个模
19、版规则。值为模式(pattern)类型。name属性标识模版是一个命名模版。priority属性定义属性的优先级。match属性值确定一个规则,用来决定模板所关联的结点类型。结点可以是一个文本元素、属性,可以是XML文档树的一个分支,还可以是与整个XML文档树。结点的这种划分叫做模式(pattern)。,8.4.1 模板,例8.4 设计包含简单元素的模板。下面是一个简单元素定义:Beijing 表示该元素的模版可以设计成:当指令xsl:apply-templates选择的结点与match属性确定的模式匹配时,执行该模版规则。,8.4.1 模板,2.应用模版 在例8.3中使用了应用模板xsl:a
20、pply-templates来处理xsl:template模板指定的元素。xsl:apply-templates指令输入一个结点序列,这个输入序列由xsl:template的matck属性决定;输出一个项目序列,该序列由xsl:apply-templates本身决定。这些项目通常是添加给结果树的结点。xsl:apply-templates的语法规则如下:,8.4.1 模板,说明:select属性用来筛选出结点,可以写,也可以不写。在xsl:apply-templates可以使用排序指令xsl:sort,输入的序列是排过序的。在xsl:apply-templates可以使用xsl:with-pa
21、ram解决参数使用问题。为了说明应用模板的使用,下面给出一个XML文档来讨论。例8.5 一个家电购买的XML文档。文档参考P.238。,8.4.1 模板,在这个XML文档中,根元素是e_appliance,在根元素下有三个子元素goods,每个goods下有两个并行的子元素,三个goods都有purchaser子元素,但另外一个元素各不相同。(1)后继元素引用方法 例8.6 在例8.5的XML文档中,引用purchaser后继name的应用模板设计方法。在select 中指明后继关系:,8.4.1 模板,从purchaser元素开始匹配,然后在select=“purchaser/name”,用
22、“/”指明name是在select 中没有后继关系:从purchaser元素开始匹配,然后在select=name没有用“/”指明name是purchaser的子元素。只有XML文档给出的隐含关系。这两种方法是等效的。,8.4.1 模板,(2)改变结果输出顺序 一般情况下,XSL文档按照XML文档的顺序输出转换结果。为了改变这种情况,可以在xsl:template中的加入多个xsl:apply-templates元素,可以改变结果内容的输出顺序。例8.7 对例8.5的结果树元素重新排列,让refrigerator比TV提前显示。,8.4.1 模板,(3)递归结构 当存在同名的后代时,可能出现两
23、个以上同时匹配的后代,其中一个又是另一个的后代。,这在网页设计中是经常使用的。此时,不做特殊处理,两个后代将分别按照常规处理。模版可以设计如下:该模版将处理外层table和内层table元素。,8.4.1 模板,(4)多模板并行 当出现上级元素调用子元素时,可以使用多个模板并行的办法来解决。例8.8 对purchaser元素下的name子元素使用多模板并行结构。姓名:第1个xsl:template通过xsl:apply-templates的select,8.4.1 模板,筛选出name子元素,第2个并行的xsl:template结构中直接使用来显示输出结果。例8.9 对purchaser下的后
24、继province子元素使用多模板并行结构。住址:,8.4.1 模板,因为province不是purchaser的直接孩子,所以使用3个并行的xsl:template结构。第1个通过xsl:apply-templates的select筛选出address子元素,第2个通过xsl:apply-templates的select筛选出province子元素,第3个直接使用来显示输出结果。例8.10 例8.5的XSL转换文档。综合上述讨论,把例8.5 XML文档的XSL转换程序设计成P.241的程序。为了方便说明,在XSL文档中加上了行号。程序说明:第1行是XML声明。,8.4.1 模板,第2行是名称
25、空间声明,在声明中必须说明version属性。第3-13行是主模板声明。9行声明模板匹配从源文档的purchaser元素开始。第14-22行声明purchaser元素的三个平级子元素。16行使用了xsl:number指令为项目编号。第23-25行的模板处理17行的模板。第28-28行的模板处理18行的模板第29-36行的模板处理19行的模板,分别声明address的各个子元素。第37-40处理 31行,41-43行处理32行,44-46行处理33行,44-46行处理33行,47-49行处理34行。,8.4.1 模板,此程序的显示结果如图8.4,图8.4 例8.10的XSL文档的显示结果,8.4
26、.1 模板,如果要求把家电名称也显示出来,可以修改9行的为:然后修改14行到22行,使之能分别处理各种家电的主要属性的显示问题,如:,8.4.1 模板,为了设计的方便,上面的XSL已经把源XML文档的TV、microwavestove、refrigerator改写成同一个元素名good,然后处理。当然,不改也行,这样XSL转换文档要复杂一些。经过修改后的结果可以显示成图8.5,读者可以参考本节内容自行设计这个XSL文档。,图8.5,8.4.1 模板,3.优先等级 当源文档的一个结点可能与几个模版规则匹配时,该怎样解决究竟选择谁的问题,这称为匹配焦点。此时,只有一个模版计算给这个结点。为了解决选
27、择谁匹配谁问题,XSLT中引入了模板的优先级(priority)。优先级如表8.1所示。匹配的步骤为:首先,只考虑匹配的模版规则具备最高的输入优先。忽略较低优先的模版。其次,在剩下的匹配规则中,只有那些具有最高优先级的被考虑,模版的优先级用属性priority 定义。如果没有,8.4.1 模板,如果没有priority属性,根据match提供的模式的语法计算默认值。如果模式包含多个选项,每个选项用“|”分隔,每个选项是等价的。一次会选择一个选项。Priority的值根据不同的形式选择不同的值,取值情况参考表8.1。,8.4.1 模板,表8.1 Priority(续),8.4.2 模式,模板规则
28、标识的结点用模式来给出应用规则。模式用来计数、分组等。模式是结点上的一组条件。满足这些条件的结点与这个模式匹配,否则不匹配。如果从一个相关的模式表达式的导出结果中选中了一个结点,就称这个结点匹配该模式。1.常用模式 在XSLT中常用到一些模式,下面是这些模式的列表。,8.4.2 模式,表8.2 XSLT的常用模式,8.4.2 模式,8.4.2 模式,2.模式语法 模式是一组用“|”分隔开来的路径表达式,路径表达式中的每一步约束成只使用孩子和属性轴的轴步骤。模式还使用/操作符。模式能以一个id或key函数调用开始。假如要匹配的值有字面值,或对一个变量或参数引用,且key函数的关键名字是一串文字。
29、这类模式不会匹配根元素不是文档结点的树。如果一个模式出现在可以使用向后兼容行为的样式表的一部分中,则该模式的语义以等价的Xpath表达式为基础来定义。,8.4.2 模式,例8.10中的几个模式使用:匹配根元素 匹配purchaser匹配purchaser应用模板 例8.11 匹配属性结点。在例2.1中,book元素附属一个属性结点isbn,在XSL程序中可以用匹配属性的方法来选择结点。在例8.1的XSL程序的14行前插入一行,book的isbn属性就会像元素结点一样显示。,8.4.3 序列构造,在计算样式表的结点组成时,需要用一种规则来计算并返回结果序列,这叫序列构造。在XSLT中序列会处理四
30、类结点:文本结点、无父元素的结点、数据项和扩展指令。序列构造所产生的结果序列的方法根据不同的指令而各不相同。文本结点:出现在样式表中,在结果序列中被复制来创建新的无父亲的文本结点。无父元素的结点:用文字结果元素的计算来创建。与文字结果元素有相同的名字,被添加到结果序列中。数据项:XSLT指令产生零个、一个或多个数据项的序列作为自己的结果。,8.4.3 序列构造,扩展指令也产生一个数据项序列作为自身的值,该序列中数据项内添加到结果序列中。1.构建复杂内容 所谓复杂内容是指内容模型包含子元素、属性、名称空间等的类型。如何通过计算序列构造得到的序列来创建新构造的文档结点的孩子,或是新建立的元素结点的
31、孩子、属性和名称空间?在XSLT中,通过xsl:copy,xsl:element,xsl:document,xsl:result-document,或文字结果元素产生序列构造,然后计算该序列构造来得到数据项序列。,8.4.3 序列构造,2.构建简单内容 一个指令创建的内容不包含子元素,这称为简单内容构建。在XSLT中,xsl:attribute、xsl:comment、xsl:processing-instruction、xsl:namespace和xsl:value-of 等指令用于简单内容的创建。其中,xsl:attribute创建属性结点、xsl:comment创建注释结点、xsl:pr
32、ocessing-instruction创建处理指令结点、xsl:namespace建立名称空间结点、xsl:value-of 建立文本结点。新结点的串值用指令的select属性来建造。select属性的内容用XPath表达式来确定。select属性和序列构造被计算后产生结果序列,新结点的串值从这个结果序列中导出。,8.4.3 序列构造,计算时,序列中的零长度的文本结点被遗弃。相邻的文本结点连接成单个文本结点。结果序列中的几个串用空格分隔符分隔后连接起来。从这个连接产生的串形成新结点、名称空间、注释、处理指令,或文本结点的串值。3.创建文本结点 本节讨论文本结点创建的指令及其用法。它们是:xs
33、l:text和xsl:value-of。一个序列构造可能包含文本结点。在处理完空格后,序列构造中保留下来的每个文本结点将建造一个新的具有相同串值的文本结点,得到的文本结点附加到包含序列构造的结果上。,8.4.3 序列构造,1)xsl:text xsl:text用于建造新的文本结点,语法为:xsl:text的内容是一个单文本结点,它的值构成新文本结点的串值。一个 xsl:text 可以为空,此时计算这个指令得到的结果是长度为零的文本结点。,8.4.3 序列构造,(2)xsl:value-of 在XSLT中,xsl:value-of是一个常用指令。指令格式为:计算xsl:value-of来建造一个
34、新的文本结点。该指令的结果产生新建造的文本结点。新文本结点的串值可以用select属性定义。例8.12 行的指令产生的结果:1|2|3|4,8.4.3 序列构造,根据元素来选择,此时select表达式是元素名称,下例中元素名为name:如果要选择元素的属性,可以在select表达式中使用来选择,下例中属性名是name。,8.4.4 循环,在XML中,有的数据以结构化形式出现,可以转换成相应的表格。要产生表格中重复的行结构,就需要从XML文档树中取出所有的结点信息,对于重复数据,使用循环结构来遍历XML中的每一个数据。如例2.1的关于图书的XML,有若干个book元素,每一本书可能产生一条记录。
35、在XSLT中,使用指令xsl:for-each来实现循环。格式为:,8.4.4 循环,说明:select属性是必须的,其expression必须是一个序列,称为输入序列。该指令根据数据项的顺序处理每一个项目,每一次计算一个出现在xsl:for-each指令顺序中的项目,然后继续下去。这个工作重复进行,直到所有的数据项都处理完为止。如果存在xsl:sort元素,输入序列被排序后生成一个有序序列。否则有序序列与输入序列相同。例8.13 使用xsl:for-each 转换例2.1的XSL文档。,8.4.4 循环,图书列表,图8.6 例2.1的XML文档用上述XSL转换的效果,8.4.4 循环,例8.
36、14 处理电影的一个XML文档,可以使用XSL实现转换。没完没了 葛尤 付彪 功夫 周兴弛 黄圣依 梁小龙 十面埋伏 刘德华 章子怡,8.4.4 循环,上面的XML文档可以具有如下的XSL转换(文件名:ch8-14.xsl):movies,图8.7 例8.14的XML文档用此XSL转换的效果,8.4.5条件处理,在XSLT中,有两种条件处理指令:xsl:if 和xsl:choose.。两者使用的方式分别讨论。1.xsl:if xsl:if的语法格式为:说明:xsl:if有一个强制性的test属性,它是逻辑型属性,expression的内容是一个序列构造。,8.4.5条件处理,xsl:if的结果
37、依据test属性表达式的值。如果返回值是真,则计算序列构造,结果的结点顺序与xsl:if 的结果一样,否则不计算序列构造,返回空序列。例8.15 控制转换直到最后一个元素。,例8.16 每隔一行产生一个黄色的背景。,8.4.5条件处理,yellow 2.xsl:choose xsl:choice在众多的可能选项中选择一个。它由一系列xsl:when跟随任选的xsl:otherwise元素组成。这三个元素的语法规则为:,8.4.5条件处理,8.4.5条件处理,说明:xsl:when和xsl:otherwise作为的子元素处理。每一个xsl:when元素有一个test表达式,xsl:when和xs
38、l:otherwise元素的内容是一个序列构造。处理xsl:choose时,每一个xsl:when依次被检查,直到满足一个xsl:when(test表达式的结果为真)为止,如果没有一个xsl:when满足表达式,则处理xsl:otherwise。在这个计算中只有第一个满足xsl:when的内容才被处理,且作为xsl:choose的结果返回。如果没有任何xsl:when满足条件,则计算xsl:otherwise,并作为xsl:choose的结果返回。如果xsl:when和xsl:otherwise都不满足条件,则xsl:choose的结果是空序列。只要找到一个满足条件的xsl:when,后面的x
39、sl:when的test不再计算。,8.5 样式表设计,在XML文档中调用XSLT文档时,需要在XML文档的序言中写上如下的行即可:例8.17 学生某学期的成绩表如下,根据该表设计XML文档和XSL转换文档。,8.5 样式表设计,此表的XML文档如下:20040112 王凌 85 78 82 58 20040101 刘雯 80 70,8.5 样式表设计,76 70 20031514 张艳丽 67 90 80 75 它的XSL转换程序如下(程序名为ch8-17.xsl):,8.5 样式表设计,student scores list 学生成绩表 学号 姓名 英语 计算机基础 高等数学 模拟电子技术
40、,8.5 样式表设计,图8.8 例8.17的XSL转换,图8.8 例8.17的XSL转换,8.5.1 排序,如果要按照某个元素的值重新排序后输出。此时要用到xsl:sort。它的语法格式为:说明:select选择被排序的元素名。排序是以什么方式排序,是升序,还是降序,由order属性决定,descending为降序,ascending为升序。,8.5.1 排序,在例8.17中的行后加上:可以按照计算机基础的成绩,从大到小排序。排序部分的代码参考如下:,8.5.2求和与求平均,1.求和 对表8.3进行求总分和每门课程求平均,可以对改表格进行下面的修改:要实现这个统计结果,应该如何设计XSL文档?
41、XML文档与表8.3的一样,要计算总分,可以使用Xpath中的算术运算进行,8.5.2求和与求平均,计算。如果求四门课程:english、computer、math、e_analog的总分,可以使用下面的XPath表达式:然后修改XSL转换文档如下:这样就可以简单地把几门功课的成绩相加。,8.5.2求和与求平均,2.求平均 求每门课程的平均成绩,在XSLT 2.0中可以使用Xpath中的数值函数avg来实现,这个函数是XSLT2.0中新增的函数。具体方法如下:如果使用的是XSLT 1.0,可以使用XPath中的数值函数sum和count来实现:其中,sum对所有的english元素值求和,co
42、unt对所有的english元素个数计数,两者相除(div)得到english的平均值。同理,可以计算其他课程的成绩。,8.5.2求和与求平均,在其他的程序设计语言中常常使用“/”作为除法运算符,为什么在XSLT中要使用div作为除法运算符?因为“/”被用作模式符(分隔父/子元素)、元素结束符标志等,所以在XSLT中把div作为除法运算符使用。在程序ch8-17.xsl中增加一行表格(即):平均分,8.5.2求和与求平均,或者:平均分,8.5.2求和与求平均,例8.18 设计计算平均值的XSL转换文档(文件名ch8-18.xsl)。程序参考P.256。如果用此XSL文档对ch8-17.XML进
43、行转换,平均分的一栏会出现多位小数位,使得显示效果不理想,此时可以用XPath中的round函数对求平均分进行四舍五入:select=“round(sum(/english)div count(/english)”。转换结果如下图表示。,8.5.2求和,图8.9 求和与求平均,8.5.3 彩色效果,如果要使表中每一行的背景有不同颜色,可以使用xsl:if来实现。在例8.19给出的XSL文档中内的后加上下面的行,可以实现隔行彩色的效果:yellow 进一步地,如果想实现每隔一行的色彩都变化,可以使用xsl:choose来实现:yellow teal,8.5.3 彩色效果,其中position()
44、函数给出当前元素所在的位置。如果要实现根据元素的内容来显示背景颜色,不同的成绩有不同的颜色。下面的选择是根据模拟电子技术课程的成绩来划分背景:red blue green yellow black,8.5.3 彩色效果,根据某门课程的不同成绩,分各种颜色来显示每个同学的成绩。小于60分的用红色,大于等于60分但小于70分的用兰色,大于等于70分但小于80分的用绿色,大于等于80分但小于90分的用黄色,90分以上的用黑色。代码如下:color:red blue green yellow black,8.5.3 彩色效果,如果只用不同颜色显示不及格的那门课程成绩,则要为每个单元格设计如下的语句。以
45、英语科目为例:color:red 或使用HTML中来设计颜色,语句如下:,8.5.3 彩色效果,这样,例8.18的for-each部分可以写成:color:red,8.5.3 彩色效果,color:red color:red color:red,8.5.3 彩色效果,读者不妨自行设计彩色效果,看看浏览器中的实际效果如何,以加深对颜色使用,以及对xsl:choose、xsl:when、xsl:otherwise和xsl:if等几个XSL元素用法的理解。,图8.10 XML文档的XSL综合转换示例,8.5.4 自动编号,在一些特定的应用中,对文本进行编号是常见的。此时可以使用xsl:number指
46、令。这也是一个常用指令。其格式为:,8.5.4 自动编号,说明:xsl:number用来创建格式化数字,对产生的结果项进行编码。该指令完成两件事,首先确定位置标记符号(可以是1、2、3,a、b、c,I、II、III等)。然后在结果序列中为文本结点的输出提供格式化符号。这个指令可以用于给章节、段落、项目等进行编号。例如在例8.10中XSL文档的16行,就是一个xsl:number的使用的例子。XSLT提供的编号功能可以对简单项目进行编号,如:1,2,A,B等。也可以对复杂项目进行编号,如A11,A1.1.1等。,8.5.4 自动编号,1.简单编号 例8.19 下面是一个编号的文本,如何设计XSL
47、文档来对该文本编号?可以把这个文本写成下面的XML文档 xsl:template xsl:apply-template,8.5.4 自动编号,xsl:eslement xsl:attribue xsl:value-of 此时,因为只有一级项目列表,使用xsl:number中的value=”position()”,在format中把格式设置成“1)、2).”。其XSL设计如下(文件名ch8-19.xsl):item list bodydisplay:block;background:#c0c0c0;width:300px;,8.5.4 自动编号,此处,使用了format属性,该属性可以取如下的值
48、:i、ii、iii、iv、v、vi I、II、III、IV、V、VI 01、02、03、04、A、B、C、D、F、G a、b、c、d、e、f(1)、(2)、(3)、(4),8.5.4 自动编号,2.复杂编号 图书目录就是一种复杂编号方式。本段我们讨论如何为一本书的目录编号,参考下面目录样式:,8.5.4 自动编号,在图8.12和图8.13中分别给出了图书目录编号的样本,后者比前者的编码复杂一些,增加了各子项目的编码。例8.20 图8.12和图8.13的XML文档。SGML HTML XML HTML文档 XML文档,8.5.4 自动编号,如何设计此文档的XSL转换?这里要用到xsl:numbe
49、r中的count属性和level属性。count属性用来指定计数的元素,如count(*)对所有元素都计数,count(section)只对section元素计数。对于例8.20,元素是chapter/section/subsection结构,要对所有级别的元素都计数,该属性应该写成:count=”chapter|section|subsection”在format 属性中分别规定编号的样式,顶级样式为“1”,下级样式为“1.1”等。对于level属性,有三种取值single、any、multiple。,8.5.4 自动编号,如果取single,只能分别显示每一单级目录的编号。any不分级别编
50、号,从第一个项目开始,顺序编号。multiple可以对多级目录分别编号。对例8.20,需要显示多级编号时,取level=”multiple”(如图8.13),只需显示单个数字的多级目录时,取level=”single”。对于图8.8,设计XSL文档(文件名:ch8.20.xsl)参考P.264。,8.5.4 自动编号,为了解决分级缩进的问题,在HTML的样式中,使用了CSS设置p的样式,分别设定了三种缩进尺寸:2em、4em、6em。如果需要把多级编号写成A,A.1,A.1.1等样式,又该如何做?例8.21 分级编号以字母开头(下面的文本段),设计XSL文档。应该怎样设计它的XML文档和XSL