SLT1.0 是W3C标准,主要用于对XML文档的转换,包括将XML转换成HMTL,TEXT或者另外格式的XML文件.XSLT1.0能够与XPATH1.0标准一块儿使用,XPATH会告诉你要转换的节点而XSLT则提供了一种机制来讲明如何实现这种转换。为了将源文档转换成想要的格式, 一个XSLT样式文件每每包含一系列的规则,而要解释这些规则, 须要依赖XSLT处理器,这个处理器实际上就是对XSLT1.0标准的实现,因此你们能够按照这个标准提供本身的实现,处理器能够根据标准元宝的全部特性来来执行规则,最终完成转换的工做。html
XSLT样式表用于定义转换逻辑,这些逻辑会应用于源XML文档的树状形式的节点集上,而后生成树状结构的节点集作为输出结果。node
下面的XML文档比较简单,咱们就以此作为源文件:编程
<!-- Emp.xml --> |
每一个XML文档必须有一个表明该文档的根结点, 而且这个根结点的子节点能够包含文档节点(具备惟一性,在上面的例子中就是<ROWSET>,你们要清楚根节点跟文档节点的区别),注释节点和指令结点。文档节点能够包含任意数量的文本节点和元素节点,同时,这些子节点仍能够包含其余任意数量的子节点,这些节点以相互嵌套的方式造成了一棵树。app
因此,要实现文档转换, 必需要有两个组成部分:函数
1 源XML文档, 在内存中,它是以树状的节点集形式表现,了解DOM的人应该容易理解。编码
2 XSLT文档,其中包含一系列的转换规则。spa
XSLT自己也是XML格式的文档,不一样的是XSLT文档支持相应的指令标签,以实现转换的功能, XSLT的文档节点是<xsl:stylesheet>,该节点下面包含全部的转换规则,每一个规则通常都与XPATH关联,XPATH代表,这个规则适用于哪一个节点,当XSLT处理器在解释源文档的某个节点的时候,会查找匹配这个节点的规则。固然,这种规则也被称作Template, 在XSLT中是用标签<xsl:template>表示,该标签有个match属性来关联XPATH表达式。好比,像下面的这个规则,它应用于源文档的根节点,”/” 是XPATH表达式,说明这个规则适用于根节点。code
<xsl:template match="/"> |
相似,像下面的模板:
<xsl:template match="ROWSET/ROW[ENAME]"> <!-- 输出的内容:文本,属性 等等. --> |
就仅做用于源文档中的<ROW>节点集,一个<ROW>节点下面还含有<ENAME>子节点,而且这个<ROW>必须是<ROWSET>节点的直接子节点,才能应用这个规则。
为何要用TEMPATE来表示一个规则呢?由于在应用这个规则的时候,包含在规则里面的文本和元素就像是个模板,每次XSLT处理程序在调用同个规则的时候,输出的结果都是以这个模板为基础的,模板保证了输出的结构是一致。
让咱们看下,如下的规则会输出什么:
<xsl:template match="ROWSET/ROW[ENAME]"> |
XSLT处理程序在解释<ROW> 节点时,会查找匹配的规则,这个模板的match属性值是“ROWSET/ROW[ENAME]”,恰好符合要求, 最后程序会调用这个模板,输出结果。
当匹配的模板被实例化后,接下来还会作三件事情:
1) 模板中的文本和属性直接输出。任何不是以XSL命名空间开头的都被认为是文本,像上面例子里的<Employee> 和 id 属性,它们会以文本形式直接输出。
2) 以大括号表示的元素,像{XPathExpr}, XSLT会计算它的值并将值以文本形式返回到当前的位置,咱们能够理解为是一个表达式点位符。
3) XSLT命名空间下的任何元素,都以文档中的前后顺序被执行。好比执行<xsl:value-of>元素,处理程序会根据select属性中的XPATH表达式获取到值,并以文本节点的形式替换<xsl:value-of>元素。
基本的逻辑能够概括为,当源文档中的节点与XSLT中的某个规则匹配的时候,规则中的内容就会输出到结果树中。一旦你掌握了这个过程, 那整个XSLT处理模型就容易理解了。 给你一个源树(XML文档的树状表示)和XSLT样式表,XSLT处理程序
依照样式表中的规则说明的那样,一步步的执行这些规则,最终将源文档转化成结果树。
在执行源树节点集的过程当中, 会产生结果树的一部分或称作“片断”,固然,到最后这些片断会被整合在一块儿。当前正在被执行的节点,称作当前节点, XSLT处理器会选择全部适用于当前节点的模板,若是适用的模板有多个,处理器会根据内置的规则(这个后面再细说),从中选取一个最匹配的,由于针对一个节点只能使用一个模板。
执行的时候,XSLT处理器从根节点开始,它搜索匹配根节点的模板,通常来讲, 匹配根节点的模板,它的match属性等于"/",找到,处理器实例化该模板,并将内容输出到结果树, 一般都要执行这三个步骤来完成工做。
若是模板还包含须要处理其余节点的XSLT指令, 那么处理器会重复上面的步骤,搜索模板,应用模板,输出结果,这是个循环的过程,直到全部的XSLT指令都被执行完成。执行完成后,转化过程产生的结果树,就是咱们想要的目标文档。
理论上说,只要定义一个模板就能够实现转化的过程,接下来,咱们会建立这样的一个模板来进行说明,固然,在一个XSLT样式表中定义多个模板,会给咱们带来更多好处,这个在后面详细介绍。
像下面的样式表,主要做用是将XML文档转换成HTML格式的文本。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
或者另一种更简洁的表示:
<!—这种方式,隐藏了匹配根节点的模板 --> <!-- |
当看到XSL命名空间的申明语句:xmlns:xsl="http://www.w3.org/1999/XSL/Transform" ,你很天然的就会想到,当执行这个样式表的时候,XSLT处理器会访问这个URL地址。然而,这个申明的做用仅仅是作为惟一的字符串来标记XSLT的命名空间, 命名空间的做用是为了区别各自的标签,由于XML是容许自定义标签的,这会致使出现相同的标签名的可能性大大增长,为了不冲突,突显自定义标签的惟一性,引入了命名空间的概念。XSLT用XSL做用命名空间的别名, <xsl:template>, <xsl:for-each>, <xsl:value-of>这些标签就代表他们是XSLT相关的标签,XSLT处理器会根据XSL前辍来识别它们,若是你移除了XSL前辍,XSLT处理器就不可能识别出它们。
考虑一下如下的样式表,它只包含一个模板,这个例子的目的就是将EMP.XML转化成HTML。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
输出结果:
![]() |
上面的模板混合了HTML的标签<html>, <body>, <table>, <tr>, and <td>,和 <xsl:for-each> and <xsl:value-of>,当XSLT处理器实例化这个模板的时候,根节点就是当前节点,
<xsl:for-each>标签 :
1) 选择源XML树中全部的"ROWSET"节点集。
2) 将选中的节点集作为当前正在处理的节点集。
3) 开始执行这些节点集。
针对节点集中的每一个节点,<xsl:for-each>里的内容都被实例化到结果树中,若是这个实例化后的片断,含有其余的XSLT元素,须要解释执行,碰到<xsl:value-of>元素的话,会用XPATH表达式计算后的结果替换当前位置。
生成的HTML:
<html> |
在这个例子中, XSLT处理器仅仅执行与根节点匹配的模板, 全部的子节点处理都依靠执行<xsl:for-each>来完成。
若是模式表只用一个模板,那么咱们能够用更简洁的方式来实现,像<xsl:stylesheet> 和<xsl:template match="/">均可以不须要。这种状况下, 文字元素在模板中是作为第一个元素。可是你必须包含XSLT的命名空间,而且要加上xsl:version="1.0"属性。
<html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
与前一个相比,写法稍有不一样,但它们输出的结果是彻底同样的,并且后一种看起来更简洁明了。
在以前的XSLT转化过程,咱们都有谈到节点树这个概念,节点的树状结构其实并不存在,它只是为了便于咱们理解的一种逻辑形式,从XSLT处理器的角度来讲,它就是一堆连续的符号,是其在内部执行源XML文档和输出转换结果的过程当中的逻辑表现形式,实际状况是:
1) 源文档是以可读的文本形式存在。
2) 转化的结果须要以其余可读的方式输出,好比,以文本形式保存到文件中或以流的方式输出到浏览器。
转换的输入信息必须是节点树,这能够经过解析源XML文档或者手动编程的方式构造出一个树(经过DOM 或SAX提供的API)。
全部的XSLT转换都是经过解析源节点树,生成结果节点树,当你的应用中有多个顺序执行的转化过程,那么一个转化过程产生的节点树会作了下个转化过程的输入,直到全部的转化过程都结束为止,全部的节点集作为一个总体以字符流的方式输出。这个过程称作序列化结果树。
根据XSLT 1.0规范的描述, 利用默认的序列化规则,在通用状况下可使咱们的XSLT文件看起来更简洁。XSLT1.0用UTF-8作为转化输出结果默认的编码集 同时还支持如下几种输出格式:
抛开这些默认的选项, 标准的XSLT语法须要以<xsl:stylesheet>开头,而后包含<xsl:output>子元素,经过这个子元素来控制输出序列化过程。
要想明白如何控制序列化,最主要的就是理解output元素中的method属性,这个属性决定XSLT处理器如何将结果集序列化到输出流。XSLT 1.0支持三种不一样的输出选项:
考虑下面文档中的例子:
<!-- King.xml --> |
用下面的XSLT样式表来转化King.xml,将 <ROWSET>节点转化成 <Invitation>:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
输出结果:
<?xml version="1.0"?> |
记住,XSLT样式表是格式良好的文档,因此有些特殊字符须要转义,像“&”转义成“&”和“<”转成“<”
还要注意的就是像“&”这样的数值型实体字符,它是数字“38”的Unicode编码形式。若是你习惯这种十六进制的表示,像换行,你能够用
来代替。
指定output为html, 下面的样式表会将<ROWSET>转化成简单的,包含图片的HTML页面。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
用这个样式表来转化King.xml,输出的结果:
<html> |
若是指定output为text将<ROWSET>转化成文本,那么输出的结果不包含任何标签:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
结果:
Hello King & Family, |
注意, 咱们转化的样式表中用<xsl:text>来处理文本内容,通常来讲, 空白字符在样式表中是被忽略的, 因此能够实现标签的缩进,以达到更好的可读性。 可是,文本内容中的空格须要被保留,<xsl:text>能够帮助咱们实现这个目的,这样,空白符就会出如今输出的文本中。除了空白字符外,还有换行符和TAB(制表符),利用<xsl:text>元素,这些符号都会被逐字保留。上面例子中的“
”表明回车换行符。
下图说明了源文档,源节点树,结果节点树和利用这三部分实现的序列化以及经过指定output,输出不一样的格式。
除了outpu属性, 还有其它几个属性能够用来控件输出行为。
![]() |
咱们都清楚, 样式表包含一组规则, 当咱们用单个模板方式的时候,整个样式表就只有一个规则:“匹配源文件的根节点,执行其中全部的XSLT指令。”这种方式,就像咱们在Java编码的时候,将全部的逻都放在一个main()函数里,确定会有人同意,有人反对。
public class doit { |
作为开发人员,刚入门的时候会以为将全部实现都放在单个方法里比较容易理解,但他们很快就会发现,当逻辑愈来愈复杂的时候,在单个方法可能有不少能够共用的部分,若是能将它们单独作为一个方法, 能够更好的提供代码的可重用性,多模板也是基本这个考虑。若是采用多模板,咱们也能够利用人家已经实现的规则,就比如站在巨人的肩膀上,可让你节约时间,并且你也能够新建一个本身规则,替换老的。
咱们能够发现,XSLT编程与JAVA编程在不少方面的相似性。在JAVA里,每一个方法是包含形为的总体并且能够被重写。若是你实现一个类,并将全部的代码逻辑都放在main()函数里,那么要是有人准备扩展你的代码,那就只能重写main()方法,尽管有时候,他们只是须要一个很小的改动。那最有效的方式,就是将一个方法中的逻辑拆分红几个子方法,并且这些子方法应用易于重用,易于重写。
在XSLT中, 模板是形为和重写的基本单元。 就像上面提到的JAVA同样,若是你将样式表中的逻辑分红多个可重用的模板, 那么其余人就有可能继承你的模板,而后调用你写好的模板或者重写模板以实现他们本身的行为逻辑。
根据每一个转化任务来拆分模板是最有效果的。你的模板越容易被调用,越容易被人重写,就说明你的拆分越合理。
下面的例子中, 咱们会将上面提到的单个模板进行细化,分红多个模板,细化后的每一个模板都对应源文档中的一个元素,负责对应元素的转化工做。每一个模板都用<xsl:apply-templates>指令告诉XSLT处理器,若是当前元素还有子元素,须要递归遍历,直到全部的节点都处理完成。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> |
咱们能够举其中的某个模板为例:
<xsl:template match="ROWSET"> |
它的含义是: 对于源文档中的<ROWSET>元素, XSLT处理器会应用这个模板来进行转化,该模板会在结果树中构建一个<table>元素,由于模板包含<xsl:apply-templates/>指令,处理器会继续查找<ROWSET>元素的全部子节点,而后用相应节点的模板来转化,直到全部的节点都转化完成,最终,各个节点的转化片断组成大的结果树,作为<table>元素的子元素。
一般状况,处理器会从源文档的根节点开始,搜索匹配的模板,在咱们的样式表中就是match="/"的那个模板,“/”符号就是表示根节点。全部这个根节点就作为当前节点被实例化。根节点模板构造出<html> 和<body> ,而后调用<xsl:apply-templates>去处理根节点的全部子节点。 这些子节点包含一个注释节点和一个元素节点<ROWSET>,为了构造这些节点的结果树片断,处理器按顺序执行全部的子节点。注释节点会被忽略(这个稍后解释),对于<ROWSET>节点,会有相匹配的模板(match等于"ROWSET")来处理。
下面的图说明XSLT处理器的顺序处理的过程。
![]() |
全部的模板都会被实例化,而后输出到结果树中。根节点模板会输出<html> 和<body>元素,"ROWSET"模板输出<table>,嵌套在<body>元素里面,接下来,执行<xsl:apply-templates>指令,匹配全部的<ROWSET>子节点,<ROWSET>节点包含如下四个节点,按顺序排列:
1. 空白节点
2. <ROW> 节点
3. 空白节点
4. <ROW> 节点
针对这些节点,处理器会查找匹配的模板,实例化模板,而后经过模板转化节点,输出到结果树中。对于空白节点,默认状况下,系统会直接拷贝空白字符,而match等于"ROW"的模板会构造出两个<tr>元素,而后继续处理其余节点。
转化完成的结果跟单个模板输出的结果是彻底一致的,可是,在接下来的几个例子中, 多模板方式会显现出其强大的好处。
在继续以前, 咱们须要解释一下,为何注释节点会被处理器忽略? 对于”7839“, ”KING“, “7788, 和“SCOTT”这样的空白节点和文本节点处理器是如何进行转化的?
要解答这些问题,不得不提到XSLT中的内置模板,这些内置模板是XSLT处理器的默认组成部分。
<xsl:template match="/|*"> 匹配根节点或任何节点,这个内置模板不输出任何东西,但会告诉处理器去执行源文档当前节点下的全部子节点。 匹配文本节点或属性节点,将当前节点的值输出。 匹配指令节点或注释节点,但什么也不作。 |
为何须要内置模板,设想一下,若是有人只想匹配源文档中的某个节点,可是默认状况下,XSLT处理器都是从根节点开始匹配,若是没有内置模板,系统会提示模板不存在就会报错,要是每一个开发人员都要将这些模板在本身的样式表中都实现,会使样式表看起来不够简洁。
会了更好的理解内置模板,咱们会用下面的样式表来转化文档”Emp.xml “,该样式表中不包含任何模板:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> |
获得的结果是:
<?xml version = '1.0' encoding = 'UTF-8'?>
|
处理器用内置的模板来匹配源文档中的元素,对于根节点元素,内置模板不会作任何的输出,只会循环遍历它的子元素,当子元素是空白元素的时候或者”7839“, ”KING“, “7788, 和“SCOTT”这样的文本元素,就会用内置的text()来匹配,调用<xsl:value-of select="."/>来拷贝当前文本节点的元素值到结果树中。 相应的, 结果树就是源文档中的一堆文本内容,来自任何层次的节点,以文档中显示的顺序输出。尽管这颇有意思,但咱们不会将这种不包含任何模板的样式表用在实际的项目中。
让咱们看下下面列出的几个模板:
<xsl:template match="EMPNO"> |
实际上,这两个模板作一样的事情,它们都用来匹配<ROW>下面的两个不一样的子节点, 而后构建一个表格元素<td>,其中包含相应子节点的转化结果树。可是,咱们要是在<ROW>增长新的节点,叫作<COMPANY>,<DEPTNO>,那是否是咱们还要创建两个新的,相似的模板呢,XSLT为咱们提供了更好的解决方案,通配符。在XPATH表达式中,咱们能够用通配符来指定某个结点下面的全部子节点,像这样”ROW/*“。用这种方式,能够再也不须要为每一个子节点设置一个匹配模板,而只要用一个泛型模板就足够了。
<!-- Match any element child of a ROW --> |
用通用的方式实现的模板,例子以下:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
输出的结果与以前的一致,可是样式表看起来更简洁。
等等, 好像跟以前的输出比较起来,仍是有不同的地方。
这段文本并无像预期的那样缩进,可是在单模板样式表中,输出的结果是排版良好的,全部节点都有缩进。
明白致使这个问题的缘由很重要,由于这关系到XSLT如何处理源文档中的空白符,回想一下,Emp.xml文档的缩进是经过空白字符和回车符实现的。若是咱们将这些都显现出来的话,应该是下面的样子。
当执行匹配<ROWSET>元素的模板的时候,XSLT处理器会构建一个<table>标签,接着循环处理<ROWSET>的全部子节点,<ROWSET>包含下面几个节点:
1. 文本节点,包含空白字符用来缩进:carriage return, space, space
2. <ROW> 节点
3. 文本节点,包含空白字符用来缩进:carriage return, space, space
4. <ROW> 节点
用多模板方式,XSLT处理器顺序执行<ROWSET>的全部子节点,查找匹配的模板。当匹配第一个空白节点的时候,由于没有明确的模板,处理器会调用内置模板"text()|@*"来处理这个节点,这个模板会将空白字符直接拷贝到结果树,对于模板来讲,空白节点跟文本节点是同样的,同时,回车符也被直接输出到结果树中,就这是致使缩进不一致的问题。
那么单模板方式为何没有这个问题? 单模板在匹配根节点后, 经过执行<xsl:for-each>指令来选择节点集,这些节点集中不包含空白节点,因此不存在上面提到的困扰。
要解决这个问题, 咱们须要告诉XSLT处理器在转化的时候,剔除这些节点,要实现这个功能, 要用到<xsl:strip-space>指令,这个指令必须放在样式表的顶部。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
与之相反,若是你要保留某个元素的空白节点,须要用<xsl:preservespace>,它一样包含有elements属性。默认状况下,XSLT处理器保留全部元素的空白节点。
前面例子中,输出的结果只有数据信息,并无包含表头,
为了建立一个通用的方式来生成表头,咱们必须遍历全部的<ROW>元素,而后取出它子节点的名称作为表格的头单元。然而,咱们已经有了一个匹配“ROW/*”的模板来处理<ROW>元素的子节点,如今为了建立表头,也须要处理这些节点,若是不一样的模板有相同的MATCH属性,XSLT处理会根据优先规则只采用其中的一个,那么如何来区分这两种不一样的应用呢,XSLT为模板提供了另一个属性MODE:
<xsl:template match="ROW/*" mode="ColumnHeaders"> |
<xsl:template match="ROWSET"> |
可是这样的写法有问题,生成表头的模板会匹配<ROWSET>下面的全部<ROW> 节点,根据<ROW> 节点的个数,会生成重复的表头信息,实际上, 咱们只要处理一个<ROW> 节点就够了。
解决这个问题很是简单,只要保证咱们的XPATH表达式只选择一个<ROW> 节点就行,修改<xsl:apply-templates mode="ColumnHeaders"/>为<xsl:apply-templates select="ROW[1]/*" mode="ColumnHeaders"/>。
咱们曾经提到过,利用多模板方式,能够重复利用已有的模板规则,甚至能够用新的模板替换老的模板,好比咱们要生成一张相似上面的表格,不一样的是,对于工资大于2000的行,要对其进行高亮显示,那咱们要如何实现呢?
假设上面提到过的一些模板都已经存放在了样式表文件TableBaseWithCSS.xsl中,而后咱们从新建了新的样式表EmpOver2000.xsl,这个文件包含新的模板,而且用<xsl:import>指定将TableBaseWithCSS.xsl引入到新的样式表中,你们都知道,TableBaseWithCSS.xsl中已经定义了转化表头和行的基本模板。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
当用EmpOver2000.xsl这个样式表来转化源文档的时候,XSLT处理器会查找<ROWSET>节点下的全部<ROW>,以前,就只有一个模板匹配这个<ROW>节点,但在新的样式表中,咱们建立了match值为ROW[SAL>2000]"的模板,这意味着对于当前节点集中的<ROW>节点,若是<SAL>这个值大于2000,处理器就会发现有两个模板匹配这个节点,咱们说过,处理器只会选择一个最合适的模板来进行匹配,在这里ROW[SAL>2000]的范围更具体,因此更适合。
让咱们再举几个例子:
下面是样式表,包含要用到的全部模板:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 匹配全部的奇数行--> |
position()函数用于取得当前的结点位置,mod 是取余操做符。
通过实验,ROW[DEPTNO=20]模板历来没用被调用过,这就说明,若是模板的优先级相同的话,处理器会永远选择最新的模板,好比当前样式表中的模板优于被引用样式表中的,文件中位置靠后的模板优先前面的。
XSLT处理器在选择合适的模板时,遵照下面的原则:
根据这种具体程序来区别多模板,万一,有多个模板,它们的程度都是同样的,处理器又该如何选择呢?一种方式就是利用priority属性,priority="realnumber"能够是任意的正负值,当处理器没法根据规则选出最恰当的模板时,模板拥有较高priority就会被选中,priority大于0.5会使你自定义的模板比内置的要优先使用。
因此,当咱们将priority="2"加到模板ROW[DEPTNO=20]中,比起匹配奇,偶行的模板,这个模板就有更高的优先级,在处理DEPTNO等于20的那行时,模板ROW[DEPTNO=20]会优先被处理器使用。
接下来,咱们看个格式化数字的例子,下面的样式表有个format-number()函数,它的做用就是将数值转换成指定的格式。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
这里,咱们仍是要引用TableBaseWithCSS.xsl,由于要用到它里面的模板,当前的样式表重写了匹配节点”ROW/SAL“的模板,并且用了另外的方式来处理变化的行,原来的方式是定义两个模板来处理奇行和偶行,如今只须要一个模板就完成这个功能:
<tr class="tr{position() mod 2}"><xsl:apply-templates/></tr> |
这个模板会构造<tr>元素到结果树,同时里面包含一个class属性,根据当前行是奇数或偶数,它的值在tr0和 tr1之间变化。CSS文件的定义以下:
body { font-family: Verdana; font-size: 8pt } |
若是,你须要常常对数值进行格式化,像是对货币格式的转换,最好是再建一个模板,以方便重用。咱们能够用name属性替换<xsl:template>的match属性。
<xsl:template name="moneyCell"> |
而后,不管何时咱们想调用模板,只要执行带name属性的<xsl:calltemplate>指令。
<xsl:call-template name="moneyCell"/> |
命名模板历来不会自动被XSLT处理器执行,除非在样式表中明确的调用。当用<xsl:call-template>调用命名模板的时候,命名模板里面的字面元素和XSL指令会被实例化,就像它们就位于调用它的模板的当前位置。
与<xsl:apply-templates select="pattern"/>不一样的是,<xsl:call-template>不会改变当前正在处理的结点,被调用的模板跟调用它的使用相同的节点,而xsl:apply-templates 会根据select属性的值改变节点位置,理解这一点很是重要。
像其余模板同样,命名模板能够被放在其余的文件里,至关于一个“方法库”文件,从而被其它样式表所引用。
常见错误当你在样式表中混搭使用基于match的模板跟命名模板的时候,会常常不经意出现错误:
|