深入XSL(4) ---模板 翻译:孙一中
1 概述
当应用于源元素的规则被确定后,就要具体实现该规则的模板.一个模板能包含文字结果的元素, 字符数据和产生结果树部分的指令.指令由XSL名域中的元素来表示,可以选择后代元素来处理. 有两类这样的指令, xsl:process-children 和xsl:process; xsl:process-children指令处理源元素的邻近子元素, 而xsl:process指令处理由指定模式来选择的元素.见下例:
<xsl:template match="chapter/title"> <fo:rule-graphic/> <fo:block space-before="2pt"> <xsl:text>Chapter </xsl:text> <xsl:number/> <xsl:text>: </xsl:text> <xsl:process-children/> </fo:block> <fo:rule-graphic/> </xsl:template>
2 文字结果元素
在一个模板中,样式表中不属于XSL名域的元素具体化将产生相同类型的节点;生成的元素节点会有已经对在模板树中的元素规定的属性. 文字结果元素的一个属性的值被认为是一个属性值模板:它能包含在花括号({})中的字符串. 结果元素节点的名域前缀映射是在样式表中移去映射到XSL名域的URI后的映射.因为XSL处理器只作用于属于XSL名域的元素,所以就有这样的问题:如何新建属于XSL名域的元素?URI是http://www.w3.org/TR/WD-xsl的名域如果紧接出现一个或多个的/quote成为被引用的名域.应用名域将作特殊处理.
3 命名属性集
xsl:define-attribute-set元素定义了一自命名的属性集合. "name"属性规定了属性集的名称. xsl:define-attribute-set元素的内容是一个规定属性的xsl:attribute-set元素.一个文字结果元素或者一个xsl:attribute-set元素能指定一属性集名称为xsl:use属性的值.下面的例子产生了一个称为title-style的属性集并在模板规则中使用它.
<xsl:define-attribute-set name="title-style"> <xsl:attribute-set font-size="12pt" font-weight="bold"/> </xsl:define-attribute-set> <xsl:template match="chapter/heading"> <fo:block xsl:use="title-style" quadding="start"> <xsl:process-children/> </fo:block> </xsl:template>
4 模板中的文字
模板也能包含PCDATA(Parsed Character Data). 在模板中去除空格后的每个数据字符将在结果树中产生一个数据字符.文字的数据字符也可以包装在一个xsl:text元素中.这样的包装处理可能改变空格的去除但不影响XSL处理器对字符的处理.
5 xsl:process-children的处理
下例新建用于chapter元素的块(block) 并处理它的相邻子元素.
<xsl:template match="chapter"> <fo:block> <xsl:process-children/> </fo:block> </xsl:template>
xsl:process-children指令处理当前节点的所有子节点,包括字符. 处理源树中的字符是将字符添加到结果树.因此,其中的<标记在源树中表示<字符,该源树将由内置的模板规则在结果树中转换为<字符,而当结果树具体化为一个XML文档时,<字符又将表示为< .
6 xsl:process的处理
xsl:process元素处理由一个模式选择的元素. xsl:process 元素的模式是一个选择模式,因而它被间接地定位到当前节点.下面的例子对author-group的所有author子节点进行处理:
<xsl:template match="author-group"> <fo:sequence> <xsl:process select="author"/> </fo:sequence> </xsl:template>
xsl:process元素处理所有匹配规定模式的元素.字符数据不被xsl:process元素匹配.模式不能包含属性模式(AttributePattern)除非它作为属性限定(AttributeQualifier)的一部分. 模式控制了发生匹配的深度.下例处理所有author节点中first-name元素:
<xsl:template match="author-group"> <fo:sequence> <xsl:process select="author/first-name"/> </fo:sequence> </xsl:template>
在模式中使用//操作符可以匹配任意的深度. 下例处理在book元素中的所有heading元素.
<xsl:template match="book"> <fo:block> <xsl:process select=".//heading"/> </fo:block> </xsl:template>
7 直接处理
当结果是已知的规则结构,能够直接确定选择元素的模板是很有益的. xsl:for-each元素包括一个模板,它具体实现由select属性规定的每个选择元素.比如对下面的XML文档:
<customers> <customer> <name>...</name> <order>...</order> <order>...</order> </customer> <customer> <name>...</name> <order>...</order> <order>...</order> </customer> </customers>
下面的XSL将生成一个HTML文档,包括一个表格,其中的一行就为一个custom元素
<xsl:template match="/"> <HTML> <HEAD> <TITLE>Customers</TITLE> </HEAD> <BODY> <TABLE> <TBODY> <xsl:for-each select="customers/customer"> <TR> <TH> <xsl:process select="name"/> </TH> <xsl:for-each select="order"> <TD> <xsl:process-children/> </TD> </xsl:for-each> </TR> </xsl:for-each> </TBODY> </TABLE> </BODY> </HTML> </xsl:template>
8 模板中的条件
XSL中有两个指令来支持条件处理: xsl:if和xsl:choose. xsl:if指令提供简单的if-then的条件选择; xsl:choose支持多条件的选择.
9 计算产生的文本
在模板中, xsl:value-of元素能用于计算产生的文本,比如通过从源树中提取文本或插入字符常数的值. 它由xsl:value-of元素通过一个规定为expr 属性值的字串表达式来实现. 字串表达式也能在文字结果元素的属性值中使用,只要将该字串表达式套入{}中.
10 宏
宏能产生结果集合还能被引用,就象一个单独的对象.在下例中,为一封装的段落定义了一个宏,在其内容之前增加“Warning!”语句.在匹配warning元素的规则中该宏被引用.
<xsl:define-macro name="warning-para"> <fo:box> <fo:block> <xsl:text>Warning! </xsl:text> <xsl:contents/> </fo:block> </fo:box> </xsl:define-macro> <xsl:template match="warning"> <xsl:invoke macro="warning-para"> <xsl:process-children/> </xsl-invoke> </xsl:template>
------------------------------------------------------------------------------- |