资源描述
第八章第八章 XSL转换转换XML第八章第八章 XSL转换转换XML 8.1 概述概述 8.2 一个一个XSL文档的讨论文档的讨论 8.3 XSL样式表样式表 8.4 模板规则模板规则 8.5 样式表设计样式表设计8.1 8.1 概述概述 本章讨论本章讨论XMLXML文档的另一种转换技术文档的另一种转换技术XSLXSL(XML XML stylesheetstylesheet language-XML language-XML样式表语言)。样式表语言)。W3CW3C在推出在推出XML 1.0XML 1.0规范后,便开始开发符合规范后,便开始开发符合XMLXML规范要规范要求的转换技术,这就是求的转换技术,这就是XSLXSL。X S LX S L 包 含 两 个 部 分:一 个 是包 含 两 个 部 分:一 个 是 X S L TX S L T(X S L X S L TransformationTransformation),另一个是定义格式的),另一个是定义格式的XMLXML词表。词表。XSLXSL定义定义一个一个XMLXML文档的样式,这个定义用文档的样式,这个定义用XSLTXSLT描写描写XMLXML文档是如何转文档是如何转换成另一个使用格式化词表的换成另一个使用格式化词表的XMLXML文档的。文档的。8.1 8.1 概述概述 19991999年年1111月月1616日,日,W3CW3C发布了发布了XSLT 1.0XSLT 1.0。在。在20012001年年1212月月2020日发布了日发布了XSLT 2.0XSLT 2.0,之后相继推出,之后相继推出7 7个修订版。个修订版。XSLT2.0XSLT2.0规范包含:样式表结构,数据模型,规范包含:样式表结构,数据模型,XSLTXSLT语言,语言,模式,模版规则模式,模版规则等内容。本书的等内容。本书的XSLTXSLT以以2.02.0规范作为蓝规范作为蓝本进行讨本进行讨8.2 8.2 一个一个XSL文档的讨论文档的讨论 在例在例2.12.1中我们给出了一个中我们给出了一个XMLXML文档,现在着手设计一个文档,现在着手设计一个简单的简单的XSLXSL转换文档来进行转换,在后续的章节逐步深入展转换文档来进行转换,在后续的章节逐步深入展开讨论。开讨论。例例8.1 8.1 根据例根据例2.12.1的的XMLXML文档,设计一个简单的文档,设计一个简单的XSLXSL文件文件进行转换。进行转换。图图8.1 8.1 例例2.1 XML2.1 XML文档的树型结构文档的树型结构 分析:在例分析:在例2.12.1的的XMLXML文档中根元素是文档中根元素是booklistbooklist,在,在bookistbookist下有若干个下有若干个bookbook子元素,子元素,bookbook下有下有namename、authorauthor、presspress、pubdatepubdate、priceprice五个子元素和一个属性五个子元素和一个属性isbnisbn。文档。文档的结构如图的结构如图8.18.1示。用示。用XSLXSL格式化该格式化该XMLXML文档,设计要求为:文档,设计要求为:8.2 8.2 一个一个XSL文档的讨论文档的讨论 为根元素建立容器,容纳其所有的子元素。为根元素建立容器,容纳其所有的子元素。每个每个bookbook显示在屏幕的一个行区域。显示在屏幕的一个行区域。每个每个bookbook的子元素显示成一个单元。的子元素显示成一个单元。我们可以为例我们可以为例2.12.1设计一个设计一个XSLXSL(文件名:(文件名:ch8-1.xslch8-1.xsl):):112 x s l:s t y l e s h e e t v e r s i o n=2.0 2=http:/www.w3.org/1999/XSL/Transform3 xsl:template3 match=/4 4 5 5 图书信息图书信息6 6 7 7 8 font size=“6”color=“teal”face=“8 图书信息图书信息 8.2 8.2 一个一个XSL文档的讨论文档的讨论 9 xsl:for9 -each select=booklist/book10 xsl:value10-of select=name/11 xsl:value11-of select=author/12 xsl:value12-of select=press/13 xsl:value-of select=pubdate13/14 xsl:value14-of select=price/16 16 15 /xsl:for15 -each 17 17 18 18 19 /xsl:template19 20 /xsl:stylesheet20 8.2 8.2 一个一个XSL文档的讨论文档的讨论 程序说明:程序说明:XSL XSL程序是符合程序是符合XMLXML规范的文档,所以,第规范的文档,所以,第1 1行是该文行是该文档为档为XMLXML文档的声明。文档的声明。第第2 2行的行的xsl:stylesheet 声明此文件是声明此文件是XSLXSL的表单的表单文件,其中的文件,其中的versionversion声明该文档的版本号,声明该文档的版本号,xmlns:xslxmlns:xsl属性属性给出此给出此XSLXSL表单文件的名称空间。该声明需要结束符表单文件的名称空间。该声明需要结束符/xsl:stylesheet 关闭(关闭(2020行)。行)。3-1 93-1 9 行 是 一 个 整 体,用行 是 一 个 整 体,用 /xsl:template 定义一个模板,其中的属性定义一个模板,其中的属性match=“/”match=“/”用用来选择该模板从根元素开始构建一个容器。来选择该模板从根元素开始构建一个容器。8.2 8.2 一个一个XSL文档的讨论文档的讨论 4-18 4-18行,借助行,借助HTMLHTML来显示来显示XMLXML元素内容。元素内容。9-15 9-15行使用了循环命令行使用了循环命令xsl:for-each,其中的属,其中的属性性selectselect用来筛选出显示的元素,这是一个用来筛选出显示的元素,这是一个XPathXPath表达式。表达式。作用是组织循环,显示作用是组织循环,显示booklistbooklist下的所有下的所有bookbook元素。元素。10-1410-14行使用取值命令行使用取值命令xsl:value-of取出个元素的取出个元素的值,其中的值,其中的selectselect用来筛选某个具体的元素值。为了显示成用来筛选某个具体的元素值。为了显示成一行,使用一行,使用HTMLHTML的段落标记元素的段落标记元素来划分段落。每一来划分段落。每一个元素值后用顿号个元素值后用顿号“、”分隔。分隔。当设计好上述的当设计好上述的XSLXSL文档后,在例文档后,在例2.12.1的第二行加上:的第二行加上:?xml-stylesheet type=text/xsl href=ch8-1.xsl?8.2 8.2 一个一个XSL文档的讨论文档的讨论 然后在浏览器上显示结果如图然后在浏览器上显示结果如图8.28.2所示。所示。图图8.2 8.2 用用ch8-1.xslch8-1.xsl转换转换ch2-1.xmlch2-1.xml8.2 8.2 一个一个XSL文档的讨论文档的讨论 1.1.什么是什么是XSLTXSLT 以样式表(以样式表(stylesheetstylesheet)的形式来表示)的形式来表示XMLXML文档,把文档,把XMLXML文档的元素用特定转换命令实现转换,这就是文档的元素用特定转换命令实现转换,这就是XSLTXSLT。在转换在转换XMLXML源文档时,源文档时,XSLTXSLT的任务是把样式信息添加给的任务是把样式信息添加给一个一个XMLXML源文件,并把它转换成包含源文件,并把它转换成包含XSLXSL格式化对象的文档,格式化对象的文档,如如HTMLHTML、XHTMLXHTML等。样式表就是这个转换技术的核心之一。等。样式表就是这个转换技术的核心之一。在在XSLTXSLT中使用一种叫转换表达式的东西,来描述把源文中使用一种叫转换表达式的东西,来描述把源文档树转换成结果树的方法和语法规则。这个转换表达式的规档树转换成结果树的方法和语法规则。这个转换表达式的规则由则由XPathXPath规范定义,有关规范定义,有关XPathXPath的内容请参考第的内容请参考第5 5章。章。8.2 8.2 一个一个XSL文档的讨论文档的讨论 文档树的结构用数据模型说明。转换由一组模版规则来文档树的结构用数据模型说明。转换由一组模版规则来实现。模版实现。模版(template)(template)把树的层次结构构成的元素序列与模把树的层次结构构成的元素序列与模式(式(patternpattern)相联系,模式与源文档的结点值匹配。许多)相联系,模式与源文档的结点值匹配。许多情况下,计算这个元素序列会产生新结点作为结果树的一部情况下,计算这个元素序列会产生新结点作为结果树的一部分。结果树与源树的结构可能相同,也可能完全不同。在构分。结果树与源树的结构可能相同,也可能完全不同。在构造结果树的过程中,源树的结点可能被过滤掉或被重新排序,造结果树的过程中,源树的结点可能被过滤掉或被重新排序,还可能加上其他任意结构。这个机制允许样式表能够应用到还可能加上其他任意结构。这个机制允许样式表能够应用到各种用途的文档,这些文档具有类似源树结构的构造形态。各种用途的文档,这些文档具有类似源树结构的构造形态。一般情况下,样式表包含的元素可以是用一般情况下,样式表包含的元素可以是用XSLTXSLT定义的,定义的,也可以不是。当样式表包含的元素是用也可以不是。当样式表包含的元素是用XSLTXSLT定义时,必须使定义时,必须使8.2 8.2 一个一个XSL文档的讨论文档的讨论 用用XSLTXSLT的名称空间间来进行限定。的名称空间间来进行限定。XSLTXSLT的名称空间规定为:的名称空间规定为:http:/www.w3.org/1999/XSL/Transformhttp:/www.w3.org/1999/XSL/Transform。例如,在例。例如,在例8.18.1中中xslxsl文件的第文件的第2 2行,我们使用了这个行,我们使用了这个URIURI,来规定在整个文,来规定在整个文件中的件中的XSLTXSLT元素都使用元素都使用XSLTXSLT的这个名称空间。的这个名称空间。2.2.样式表样式表 样式表是用样式表是用xsl:stylesheetxsl:stylesheet元素或元素或xsl:transformxsl:transform元素元素定义的一个整体,由一个以上的模块组成。每一个模块形成定义的一个整体,由一个以上的模块组成。每一个模块形成一个一个XMLXML文档的整体或某个部分。每个样式表模块的形成由文档的整体或某个部分。每个样式表模块的形成由数据模型中的一个元素结点来表现。数据模型中的一个元素结点来表现。样式表模块分为标准和简化两种。样式表模块分为标准和简化两种。8.2 8.2 一个一个XSL文档的讨论文档的讨论 3.3.模版规则模版规则 XSLTXSLT技术以技术以“模板驱动模板驱动”的方式访问的方式访问XMLXML数据,通过引进数据,通过引进模板来访问模板来访问XMLXML数据元素及其属性。数据元素及其属性。模版规则定义一个处理容器,这个处理能够用于匹配特模版规则定义一个处理容器,这个处理能够用于匹配特定模式的结点。一个模版由一个带定模式的结点。一个模版由一个带xsl:templatexsl:template声明来定义。声明来定义。一个一个xsl:templatexsl:template元素必须具有一个元素必须具有一个matchmatch或或namename属性,或两属性,或两者都有。如果一个者都有。如果一个xsl:templatexsl:template元素带有元素带有matchmatch属性,它就是属性,它就是一个模版规则。如果一个一个模版规则。如果一个xsl:templatexsl:template元素带有元素带有namename属性,属性,它就是命名模版。它就是命名模版。8.2 8.2 一个一个XSL文档的讨论文档的讨论 模版的引用有许多方法,这要根据它是模版规则、模版的引用有许多方法,这要根据它是模版规则、还是命名模版来决定。引用模版的结果就是计算包含在还是命名模版来决定。引用模版的结果就是计算包含在xsl:templatexsl:template元素中的序列构造的结果。元素中的序列构造的结果。8.3.1 8.3.1 样式表元素样式表元素1.1.定义样式表定义样式表 在在 X S LX S L 中,样 式 表 元 素中,样 式 表 元 素 用用 x s l:s t y l e s h e e t x s l:s t y l e s h e e t 和和xsl:transformxsl:transform来表示。来表示。xsl:stylesheetxsl:stylesheet是一个表示样式表是一个表示样式表模块的模块的XMLXML元素元素,xsl:transformxsl:transform是是xsl:stylesheetxsl:stylesheet的同义词,的同义词,所以说这两个元素是等价的。它们的语法格式的简化形式分所以说这两个元素是等价的。它们的语法格式的简化形式分别为:别为:8.3.1 8.3.1 样式表元素样式表元素 如例如例8.18.1中的中的XSLXSL文件中的第文件中的第2 2行:行:就是一个样式表定义。这行代码告诉就是一个样式表定义。这行代码告诉XSLTXSLT解析器现在执行的解析器现在执行的是一个是一个XSLXSL转换样式表文件。转换样式表文件。2.2.样式表子元素样式表子元素 在一个样式表中,可以使用在在一个样式表中,可以使用在xsl:stylesheetxsl:stylesheet元素之下元素之下的子元素叫顶层元素。常用的顶层元素有:的子元素叫顶层元素。常用的顶层元素有:xsl:templatexsl:template、xsl:importxsl:import、xsl:includexsl:include、xsl:functionxsl:function、xsl:outputxsl:output、xsl:paramxsl:param、xsl:variablexsl:variable。8.3.1 8.3.1 样式表元素样式表元素3.3.简化样式表模块简化样式表模块 一个简化样式表是一个只包含文档结点的单个模版规一个简化样式表是一个只包含文档结点的单个模版规则。这个样式表模块可以仅包含文字结果元素和它的内容。则。这个样式表模块可以仅包含文字结果元素和它的内容。简化样式表规则使用匹配模式简化样式表规则使用匹配模式“/”/”。例例8.2 8.2 使用简化样式表规则使用简化样式表规则xsl:templatematch=/设计样式表。设计样式表。仍然用例仍然用例8.18.1中使用的中使用的XMLXML文档来讨论,下面是设计模块:文档来讨论,下面是设计模块:xsl:stylesheetversion =http:/www.w3.org/1999/XSL/Transform8.3.1 8.3.1 样式表元素样式表元素xsl:template match=/图书信息图书信息新书新书:xsl:value:-of select=booklist/book/name/xsl:template/xsl:stylesheet 因为我们在此简化样式表中,没有使用循环指令,因为我们在此简化样式表中,没有使用循环指令,所以只能显示第一本书的名称。所以只能显示第一本书的名称。8.3.1 8.3.1 样式表元素样式表元素其显示效果如图其显示效果如图8.28.2。作为一个简化样式表模块最外层元素的文作为一个简化样式表模块最外层元素的文字结果元素,必须具有字结果元素,必须具有xsl:versionxsl:version属性,用来属性,用来指明指明XSLTXSLT的版本。这个版本值正常取的版本。这个版本值正常取2.02.0。图图8.3 8.3 一个简化样式表一个简化样式表8.3.1 8.3.1 样式表元素样式表元素4.向前和向后兼容处理向前和向后兼容处理 因为因为XSLT 1.0XSLT 1.0是是19991999年发布的,这个年发布的,这个1.01.0版本存在许多版本存在许多弱点,如计算一个求和、平均值这样的问题,必须借助脚本弱点,如计算一个求和、平均值这样的问题,必须借助脚本语言来实现,计算功能很弱;格式化信息不丰富等。在后来语言来实现,计算功能很弱;格式化信息不丰富等。在后来的的2.02.0版本中采取了废弃一些指令元素的办法,对版本中采取了废弃一些指令元素的办法,对1.01.0作了相作了相当大的修改、完善,根本上改变了原来当大的修改、完善,根本上改变了原来1.01.0版版本的面貌。现本的面貌。现在讨论的几乎是一个全新在讨论的几乎是一个全新XSLTXSLT版本。所谓的向前和向后兼容版本。所谓的向前和向后兼容就是针对就是针对XSLT 2.0XSLT 2.0以前的版本设置的兼容技术,当一个元素以前的版本设置的兼容技术,当一个元素的的versionversion属性值小于属性值小于2.02.0时,我们说它具有向后兼容行为。时,我们说它具有向后兼容行为。当大于当大于2.02.0时说它具有向前兼容行为。时说它具有向前兼容行为。8.3.1 8.3.1 样式表元素样式表元素 向后兼容时处理器自动使用向后兼容时处理器自动使用XSLT1.0XSLT1.0来处理来处理XSLTXSLT文档。文档。向前兼容的处理器自动使用向前兼容的处理器自动使用XSLT2.0XSLT2.05.5.标准属性标准属性 为了说明标准属性,我们来参考为了说明标准属性,我们来参考xsl:stylesheexsl:styleshee元素的元素的详细格式:详细格式:8.3.1 8.3.1 样式表元素样式表元素 8.3.1 8.3.1 样式表元素样式表元素 其中出现的属性其中出现的属性extension-element-prefixesextension-element-prefixes、exclude-result-prefixesexclude-result-prefixes、versionversion、xpathxpath-default-default-namespacenamespace、default-collationdefault-collation等,就是标准属性。这些标等,就是标准属性。这些标准属性可能出现在所有的准属性可能出现在所有的XSLT XSLT 元素中。元素中。versionversion、xpathxpath-default-namespacedefault-namespace、default-collationdefault-collation几种属性,其属性几种属性,其属性值可以被出现在后继元素中的相同属性覆盖。值可以被出现在后继元素中的相同属性覆盖。因为这些属性通常只用在因为这些属性通常只用在xsl:stylesheetxsl:stylesheet元素中,它们元素中,它们对整个样式表下的子模块都有效。对整个样式表下的子模块都有效。8.XSLT8.XSLT的媒体类型的媒体类型 XSLTXSLT使用的媒体类型是:使用的媒体类型是:application/xslt+xmlapplication/xslt+xml。8.3.2 8.3.2 样式表名称空间样式表名称空间 关于名称空间的讨论,在关于名称空间的讨论,在2.32.3节曾经详细讨论过。在节曾经详细讨论过。在XSLTXSLT引入名称空间也是出于类似的考虑,因为引入名称空间也是出于类似的考虑,因为XSLTXSLT技术是面技术是面向应用的,当出现许多不同应用具有相同元素和属性名称时,向应用的,当出现许多不同应用具有相同元素和属性名称时,需要把它们分别开来,给应用程序提供分辨属于不同名称空需要把它们分别开来,给应用程序提供分辨属于不同名称空间的元素和属性的可能,这在间的元素和属性的可能,这在XSLTXSLT的应用中十分重要。的应用中十分重要。XSLTXSLT处理器必须使用处理器必须使用XMLXML名称空间机制来识别元素和属名称空间机制来识别元素和属性。来自性。来自XSLTXSLT名称空间的元素只在样式表中被识别,而不是名称空间的元素只在样式表中被识别,而不是在在XMLXML源文档中,它的名称空间与源源文档中,它的名称空间与源XMLXML的名称空间不能混淆。的名称空间不能混淆。实现工具也不能扩展具有附加元素和属性的实现工具也不能扩展具有附加元素和属性的XSLTXSLT的名称空间。的名称空间。8.3.2 8.3.2 样式表名称空间样式表名称空间1.1.保留名称空间保留名称空间 XSLTXSLT名称空间和其它被名称空间和其它被XSLTXSLT处理器识别的某些名称空间,处理器识别的某些名称空间,称为保留名称空间,必须只能在称为保留名称空间,必须只能在XSLTXSLT中使用。这些保留的名中使用。这些保留的名称空间是:称空间是:XSLTXSLT名称空间:名称空间:http:/www.w3.org/1999/XSL/Transformhttp:/www.w3.org/1999/XSL/Transform 标准函数名称空间:标准函数名称空间:http:/www.w3.org/2005/02/xpath-functions http:/www.w3.org/2005/02/xpath-functions 用来定义函数。用来定义函数。XMLXML名称空间:名称空间:http:/www.w3.org/XML/1998/namespacehttp:/www.w3.org/XML/1998/namespace用于用于xml:langxml:lang和和 xml:spacexml:space属性。属性。8.3.2 8.3.2 样式表名称空间样式表名称空间模式名称空间:模式名称空间:http:/www.w3.org/2001/XMLSchemahttp:/www.w3.org/2001/XMLSchema,用于定义,用于定义XML XML 模式。在样模式。在样式表中,这个名称空间用来引用内置的模式数据类型,以及式表中,这个名称空间用来引用内置的模式数据类型,以及用这些数据类型构造函数。用这些数据类型构造函数。XpathXpath数据类型名称空间:数据类型名称空间:http:/www.w3.org/2005/02/xpath-http:/www.w3.org/2005/02/xpath-datatypesdatatypes ,用于定义函数和,用于定义函数和运算符。运算符。模式实例名称空间:模式实例名称空间:http:/www.w3.org/2001/XMLSchema-instancehttp:/www.w3.org/2001/XMLSchema-instance,用于定义用于定义XML XML SchemaSchema。8.3.2 8.3.2 样式表名称空间样式表名称空间2.2.名称空间前缀名称空间前缀 名称空间前缀用来定义一个使用的元素与一个名称空间名称空间前缀用来定义一个使用的元素与一个名称空间的 关 联,通 常 叫 做 绑 定。如 例的 关 联,通 常 叫 做 绑 定。如 例 8.18.1 中 第中 第 2 2 行 的行 的xmlns:xslxmlns:xsl=http:/www.w3.org/1999/XSL/Transform=http:/www.w3.org/1999/XSL/Transform,就把,就把XSLTXSLT的名称空间的名称空间绑定给前缀绑定给前缀xslxsl。当然。当然XSLTXSLT可以使用任意字符串作为名称空间可以使用任意字符串作为名称空间前缀,只要它绑定给规定的前缀,只要它绑定给规定的XSLTXSLT名称空间即可。名称空间即可。8.3.3 8.3.3 样式表模块组合样式表模块组合 当一个样式表中需要对若干个当一个样式表中需要对若干个XMLXML进行转换的进行转换的XSLXSL文件时,文件时,或对同一个或对同一个XMLXML需要多种样式表模块来转换时,可以使用包需要多种样式表模块来转换时,可以使用包含机制和输入机制。包含机制不改变组合模块的语义来组合含机制和输入机制。包含机制不改变组合模块的语义来组合样式表模块。输入机制允许样式表彼此覆盖。在样式表模块。输入机制允许样式表彼此覆盖。在XSLTXSLT中,包中,包含机制和输入机制用含机制和输入机制用xsl:includexsl:include和和xsl:importxsl:import来完成。来完成。1.1.样式表包含样式表包含 包含一个样式表模块,可以使用包含一个样式表模块,可以使用xsl:includexsl:include声明,格声明,格式为:式为:8.3.3 8.3.3 样式表模块组合样式表模块组合 2.2.样式表导入样式表导入 导入一个样式表模块,可以使用导入一个样式表模块,可以使用xsl:importxsl:import声明,格式声明,格式为:为:xsl:importxsl:import声明与声明与xsl:includexsl:include一样,要求具有一样,要求具有hrefhref属性,属性,它的含义它的含义与与xsl:includexsl:include一样。这个元素必须是顶层元素。一样。这个元素必须是顶层元素。xsl:importxsl:import元素的孩子必须先于元素的孩子必须先于xsl:stylesheetxsl:stylesheet元素的所有元素的所有其它元素的孩子,包含任何的其它元素的孩子,包含任何的xsl:includexsl:include元素孩子和任何的元素孩子和任何的用户定义数据元素。用户定义数据元素。8.3.3 8.3.3 样式表模块组合样式表模块组合例例8.3 8.3 使用使用xsl:importxsl:import导入样式表模块。导入样式表模块。xsl:stylesheet=http:/www.w3.org/1999/XSL/Transform xsl:import href =ch8-1a.xsl/xsl:import href =ch8-1b.xsl/xsl:stylesheet 8.4 模板规则模板规则8.4.1模板模板1.1.定义模板定义模板 一个一个xsl:templatexsl:template声明定义一个模版,它包含创建结点声明定义一个模版,它包含创建结点和原子值的序列构造。和原子值的序列构造。模版既可以作为模版规则,用比照模版既可以作为模版规则,用比照一个模式来匹配结点的方法构造规则,也可以是命名模版,一个模式来匹配结点的方法构造规则,也可以是命名模版,用名称来明确指定。有时,一个模版可以同时具有这两种能用名称来明确指定。有时,一个模版可以同时具有这两种能力。力。模版定义的简化规则如下:模版定义的简化规则如下:8.4.1 模板模板说明:说明:matchmatch属性标识模版是一个模版规则。值为模式属性标识模版是一个模版规则。值为模式(patternpattern)类型。)类型。namename属性标识模版是一个命名模版。属性标识模版是一个命名模版。prioritypriority属性定义属性的优先级。属性定义属性的优先级。matchmatch属性值确定一个规则,用来决定模板所关联的结点属性值确定一个规则,用来决定模板所关联的结点类型。结点可以是一个文本元素、属性,可以是类型。结点可以是一个文本元素、属性,可以是XMLXML文档树文档树的一个分支,还可以是与整个的一个分支,还可以是与整个XMLXML文档树。结点的这种划分文档树。结点的这种划分叫做模式(叫做模式(patternpattern)。)。8.4.1 模板模板例例8.4 8.4 设计包含简单元素的模板。设计包含简单元素的模板。下面是一个简单元素定义:下面是一个简单元素定义:Beijing Beijing 表示该元素的模版可以设计成:表示该元素的模版可以设计成:xsl:template match=cityxsl:apply-templates/xsl:template 当指令当指令xsl:applyxsl:apply-templates-templates选择的结点与选择的结点与matchmatch属性确属性确定的模式匹配时,执行该模版规则。定的模式匹配时,执行该模版规则。8.4.1 模板模板2.2.应用模版应用模版 在例在例8.38.3中使用了应用模板中使用了应用模板xsl:applyxsl:apply-templates-templates来处理来处理xsl:templatexsl:template模板指定的元素。模板指定的元素。xsl:applyxsl:apply-templates-templates指令指令输入一个结点序列,这个输入序列输入一个结点序列,这个输入序列由由xsl:templatexsl:template的的matckmatck属性决定;输出一个项目序列,该序列由属性决定;输出一个项目序列,该序列由xsl:applyxsl:apply-templatestemplates本身决定。这些项目通常是添加给结果树的结点。本身决定。这些项目通常是添加给结果树的结点。xsl:applyxsl:apply-templates-templates的语法规则如下:的语法规则如下:8.4.1 模板模板 说明:说明:select select属性用来筛选出结点,可以写,也可以不写。属性用来筛选出结点,可以写,也可以不写。在在xsl:applyxsl:apply-templates-templates可以使用排序指令可以使用排序指令xsl:sortxsl:sort,输入的序列是排过序的。输入的序列是排过序的。在在xsl:applyxsl:apply-templates-templates可以使用可以使用xsl:with-paramxsl:with-param解解决参数使用问题。决参数使用问题。为了说明应用模板的使用,下面给出一个为了说明应用模板的使用,下面给出一个XMLXML文档来讨论。文档来讨论。例例8.5 8.5 一个家电购买的一个家电购买的XMLXML文档。文档。文档参考文档参考P.238P.238。8.4.1 模板模板 在这个在这个XMLXML文档中,根元素是文档中,根元素是e_appliancee_appliance,在根元素下,在根元素下有三个子元素有三个子元素goodsgoods,每个,每个goodsgoods下有两个并行的子元素,三下有两个并行的子元素,三个个goodsgoods都有都有purchaserpurchaser子元素,但另外一个元素各不相同。子元素,但另外一个元素各不相同。(1 1)后继元素引用方法)后继元素引用方法 例例8.68.6 在例在例8.58.5的的XMLXML文档中,引用文档中,引用purchaserpurchaser后继后继namename的应用模板设计方法。的应用模板设计方法。在在select select 中指明后继关系:中指明后继关系:xsl:template match=purchaser xsl:apply -templates select=purchaser/name/xsl:template 8.4.1 模板模板从从 p u r c h a s e rp u r c h a s e r 元 素 开 始 匹 配,然 后 在元 素 开 始 匹 配,然 后 在select=“purchaser/name”select=“purchaser/name”,用,用“/”指明指明namename是是在在select select 中没有后继关系:中没有后继关系:xsl:template match=purchaser xsl:apply -templates select=name/xsl:template 从从purchaserpurchaser元素开始匹配,然后在元素开始匹配,然后在select=nameselect=name没有没有用用“/”/”指明指明namename是是purchaserpurchaser的子元素。只有的子元素。只有XMLXML文档给出文档给出的隐含关系。这两种方法是等效的。的隐含关系。这两种方法是等效的。8.4.1 模板模板(2 2)改变结果输出顺序)改变结果输出顺序 一般情况下,一般情况下,XSLXSL文档按照文档按照XMLXML文档的顺序输出转换结果。文档的顺序输出转换结果。为了改变这种情况,可以在为了改变这种情况,可以在xsl:templatexsl:template中的加入多个中的加入多个xsl:applyxsl:apply-templates-templates元素,可以改变结果内容的输出顺序。元素,可以改变结果内容的输出顺序。例例 8.7 8.7 对 例对 例 8.58.5 的 结 果 树 元 素 重 新 排 列,让的 结 果 树 元 素 重 新 排 列,让refrigeratorrefrigerator比比TVTV提前显示。提前显示。xsl:template match=e_appliance xsl:apply -templates select=goods/refrigerator/xsl:apply -templates select=goods/TV/xsl:template 8.4.1 模板模板(3 3)递归结构)递归结构 当存在同名的后代时,可能出现两个以上同时匹配的后当存在同名的后代时,可能出现两个以上同时匹配的后代,其中一个又是另一个的后代。代,其中一个又是另一个的后代。/table,这在,这在网页设计中是经常使用的。此时,不做特殊处理,两个后代网页设计中是经常使用的。此时,不做特殊处理,两个后代将分别按照常规处理。模版可以设计如下:将分别按照常规处理。模版可以设计如下:xsl:template match=html xsl:apply -templates select=./table/xsl:template 该模版将处理外层该模版将处理外层tabletable和内层和内层tabletable元素。元素。8.4.1 模板模板(4 4)多模板并行)多模板并行 当出现上级元素调用子元素时,可以使用多个模板并行当出现上级元素调用子元素时,可以使用多个模板并行的办法来解决。的办法来解决。例例8.8 8.8 对对purchaserpurchaser元素下的元素下的namename子元素使用多模板并子元素使用多模板并行结构。行结构。xsl:template match=purchaser xsl:apply -templates select=name/xsl:template xsl:template match=name 姓名:姓名:xsl:apply-templates/xsl:template 第第1 1个个xsl:templatexsl:template通过通过xsl:applyxsl:apply-templates-templates的的selectselect 8.4.1 模板模板筛选出筛选出namename子元素,第子元素,第2 2个并行的个并行的xsl:templatexsl:template结构中直接结构中直接使用使用xsl:apply-templates/来显示输出结果。来显示输出结果。例例8.9 8.9 对对purchaserpurchaser下的后继下的后继provinceprovince子元素使用多模子元素使用多模板并行结构。板并行结构。xsl:template match=purchaser xsl:apply -templates select=address/xsl:template xsl:template match=address xsl:apply -templates select=province/xsl:template xsl:template match=province 住址:住址:xsl:apply-templates/xsl:template 8.4.1 模板模板因为因为provinceprovince不是不是purchaserpurchaser的直接孩子,所以使用的直接孩子,所以使用3 3个并行个并行的的xsl:templatexsl:template结构。第结构。第1 1个通过个通过xsl:applyxsl:apply-templates-templates的的selectselect筛选出筛选出addressaddress子元素,第子元素,第2 2个通过个通过xsl:applyxsl:apply-templatestemplates的的selectselect筛选出筛选出provinceprovince子元素,第子元素,第3 3个直接使用个直接使用xsl:apply-templates/来显示输出结果。来显示输出结果。例例8.10 8.10 例例8.58.5的的XSLXSL转换文档。转换文档。综合上述讨论,把例综合上述讨论,把例8.5 XML8.5 XML文档的文档的XSLXSL转换程序设计成转换程序设计成P.241P.241的程序。为了方便说明,在的程序。为了方便说明,在XSLXSL文档中加上了行号。文档中加上了行号。程序说明:程序说明:第第1 1行是行是XMLXML声明。声明。8.4.1 模板模板第第2 2行是名称空间声明,在声明中必须说明行是名称空间声明,在声明中必须说明versionversion属性。属性。第第3-133-13行是主模板声明。行是主模板声明。9 9行声明模板匹配从源文档的行声明模板匹配从源文档的purchaserpurchaser元素开始。元素开始。第第14-2214-22行声明行声明purchaserpurchaser元素的三个平级子元素。元素的三个平级子元素。1616行行使用了使用了xsl:numberxsl:number指令为项目编号。指令为项目编号。第第23-2523-25行的模板处理行的模板处理1717行的模板。行的模板。第第28-2828-28行的模板处理行的模板处理1818行的模板行的模板第第29-3629-36行的模板处理行的模板处理1919行的模板,分别声明行的模板,分别声明addressaddress的的各个子元素。各个子元素。第第37-4037-40处理处理 3131行,行,41-4341-43行处理行处理3232行,行,44-4644-46行处理行处理3333行,行,44-4644-46行处理行处理3333行,行,47-4947-49行处理行处理3434行。行。8.4.1 模板模板此程序的显示结果如图此程序的显示结果如图8.48.4图图8.4 例例8.10的的XSL文档的显示结果文档的显示结果 8.4.1 模板模板如果要求把家电名称也显示出来,可以修改如果要求把家电名称也显示出来,可以修改9 9行的为:行的为:xsl:apply-templates select=e_appliance/goods/然后修改然后修改1414行到行到2222行,使之能分别处理各种家电的主要行,使之能分别处理各种家电的主要属性的显示问题,如:属性的显示问题,如:xsl:template match=goods xsl:apply -templates select=good/xsl:apply -templates select=purchaser/xsl:template xsl:template match=good table border=1 cellspacing=1 bordercolor =blue xsl:apply -templates select=producer/xsl:apply -templates select=size/xsl:apply -templates select=unit/xsl:apply -templates select=price/xsl:template 8.4.1 模板模板 为了设计的方便,上面的为了设计的方便,上面的XSLXSL已经把源已经把源XMLXML文档的文档的TVTV、microwavestovemicrowavestove、refrigeratorrefrigerator改写成同一个元素名改写成同一个元素名goodgood,然后处理。当然,不改也行,这样然后处理。当然,不改也行,这样XSLXSL转换文档要复杂一些。转换文档要复杂一些。经过修改后的结果可以显示成图经过修改后的结果可以显示成图8.58.5,读者可以参考本节内容,读者可以参考本节内容自行设计这个自行设计这个XSLXSL文档。文档。图图8.58.5 8.4.1 模板模板 3.3.优先等级优先等级 当源文档的一个结点可能与几个模版规则匹配时,该怎当源文档的一个结点可能与几个模版规则匹配时,该怎样解决究竟选择谁的问题,这称为匹配焦点。此时,只有一样解决究竟选择谁的问题,这称为匹配焦点。此时,只有一个模版计算给这个结点。为了解决选择谁匹配谁问题,个模版计算给这个结点。为了解决选择谁匹配谁问题,XSLTXSLT中引入了模板的优先级(中引入了模板的优先级(prioritypriority)。优先级如表)。优先级如表8.18.1所示。所示。匹配的步骤为:匹配的步骤为:首先,只考虑匹配的模版规则具备最高的输入优先。首先,只考虑匹配的模版规则具备最高的输入优先。忽略较低优先的模版。忽略较低优先的模版。其次,在剩下的匹配规则中,只有那些具有最高优先其次,在剩下的匹配规则中,只有那些具有最高优先级的被考虑,模版的优先级用属级的被考虑,模版的优先级用属性性priority priority 定义。定义。如果没有如果没有 8.4.1 模板模板如果没有如果没有prioritypriority属性,根据属性,根据matchmatch提供的模式的语法提供的模式的语法计计算默认值。算默认值。如果模式包含多个选项,每个选项用如果模式包含多个选项,每个选项用“|”“|”分分隔,每个选项是等价的。一次会选择一个选项。隔,每个选项是等价的。一次会选择一个选项。PriorityPriority的值根据不同的形式选择不同的值,取值的值根据不同的形式选择不同的值,取值情况参考表情况参考表8.18.1。格式格式PriorityPriority说明说明element()element()0.50.5与与*等价等价element(element(*)0.50.5与与*等价等价attribute()attribute()0.50.5与与*等价等价attribute(attribute(*)0.50.5与与*等价等价element(element(E E)0 0与与E E等价等价element(element(*,T T)0 0只匹配类型只匹配类型attribute(attribute(A A)0 0与与AA等价等价 8.4.1 模板模板 表表8.1 Priority 8.1 Priority(续)(续)格式格式PriorityPriority说明说明attribute(attribute(*,T T)0 0只匹配类型只匹配类型element(element(E E,T T)0.250.25匹配名称与类型匹配名称与类型schema-element(schema-element(E E)0.250.25匹配替换组和类型匹配替换组和类型attribute(attribute(A A,T T)0.250.25匹配名称和类型匹配名称和类型schema-attribute(schema-attribute(A A)0.250.25匹配名称和类型匹配名称和类型 8.4.2 模式模式 模板规则标识的结点用模式来给出应用规则。模式用来模板规则标识的结点用模式来给出应用规则。模式用来计数、分组等。模式是结点上的一组条件。满足这些条件的计数、分组等。模式是结点上的一组条件。满足这些条件的结点与这个模式匹配,否则不匹配。如果从一个相关的模式结点与这个模式匹配,否则不匹配。如果从一个相关的模式表达式的导出结果中选中了一个结点,就称这个结点匹配该表达式的导出结果中选中了一个结点,就称这个结点匹配该模式。模式。1.1.常用模式常用模式 在在XSLTXSLT中常用到一些模式,下面是这些模式的列表。中常用到一些模式,下面是这些模式的列表。8.4.2 模式模式 表表8.2 XSLT8.2 XSLT的常用模式的常用模式 8.4.2 模式模式 8.4.2 模式模式2.2.模式语法模式语法 模式是一组用模式是一组用“|”|”分隔开来的路径表达式,路径表达分隔开来的路径表达式,路径表达式中的每一步约束成只使用孩子和属性轴的轴步骤。模式还式中的每一步约束成只使用孩子和属性轴的轴步骤。模式还使用使用/操作符。操作符。模式能以一个模式能以一个idid或或keykey函数调用开始。假如要匹配的值函数调用开始。假如要匹配的值有字面值,或对一个变量或参数引用,且有字面值,或对一个变量或参数引用,且keykey函数的关键名函数的关键名字是一串文字。这类模式不会匹配根元素不是文档结点的树。字是一串文字。这类模式不会匹配根元素不是文档结点的树。如果一个模式出现在可以使用向后兼容行为的样式表的如果一个模式出现在可以使用向后兼容行为的样式表的一部分中,则该模式的语义以等价的一部分中,则该模式的语义以等价的XpathXpath表达式为基础来表达式为基础来定义。定义。8.4.2 模式模式例例8.108.10中的几个模式使用:中的几个模式使用:xsl:template match=/匹配根元素匹配根元素xsl:template match=e_appliance/goods/purchaser 匹配匹配purchaserpurchaserxsl:template match=purchaser匹配匹配purchaserpurchaserxsl:apply-templates select=“province”/应用模板应用模板 例例8.11 8.11 匹配属性结点。匹配属性结点。在例在例2.12.1中,中,bookbook元素附属一个属性结点元素附属一个属性结点isbnisbn,在,在XSLXSL程程序中可以用匹配属性的方法来选择结点。在例序中可以用匹配属性的方法来选择结点。在例8.18.1的的XSLXSL程序程序的的1414行前插入行前插入xsl:value-of select=“isbn”/一行,一行,bookbook的的isbnisbn属性就会像元素结点一样显示。属性就会像元素结点一样显示。8.4.3 序列构造序列构造在计算样式表的结点组成时,需要用一种规则来计算并在计算样式表的结点组成时,需要用一种规则来计算并返回结果序列,这叫序列构造。在返回结果序列,这叫序列构造。在XSLTXSLT中序列会处理四类结中序列会处理四类结点:文本结点、无父元素的结点、数据项和扩展指令。序列点:文本结点、无父元素的结点、数据项和扩展指令。序列构造所产生的结果序列的方法根据不同的指令而各不相同。构造所产生的结果序列的方法根据不同的指令而各不相同。文本结点:出现在样式表中,在结果序列中被复制来创文本结点:出现在样式表中,在结果序列中被复制来创建新的无父亲的文本结点。建新的无父亲的文本结点。无父元素的结点:用文字结果元素的计算来创建。与文无父元素的结点:用文字结果元素的计算来创建。与文字结果元素有相同的名字,被添加到结果序列中。字结果元素有相同的名字,被添加到结果序列中。数据项:数据项:XSLTXSLT指令产生零个、一个或多个数据项的序列指令产生零个、一个或
展开阅读全文