您的位置:首页 > 其它

XSLT 1.0推荐标准摘译(第四部分)

2009-07-01 16:46 381 查看
8


重复


<!-- Category: instruction -->

<xsl:for-each

select = node-set-expression>

<!-- Content: (
xsl:sort

*, template) -->

</xsl:for-each>

必要属性select
中的表达式计算结果必须是一个节点集。比如XML
文档:

<customers>

<customer>

<name>...</name>

<order>...</order>

<order>...</order>

</customer>

<customer>

<name>...</name>

<order>...</order>

<order>...</order>

</customer>

</customers>

下例将遍历每个客户生成一张表:

<xsl:template
match="/">

<html>

<head>

<title>Customers</title>

</head>

<body>

<table>

<tbody>

<xsl:for-each
select="customers/customer">

<tr>

<th>

<xsl:apply-templates
select="name"/>

</th>

<xsl:for-each
select="order">

<td>

<xsl:apply-templates/>

</td>

</xsl:for-each>

</tr>

</xsl:for-each>

</tbody>

</table>

</body>

</html>

</xsl:template>

9


条件处理


9.1


xsl:if


<!-- Category: instruction -->

<xsl:if

test = boolean-expression>

<!-- Content: template -->

</xsl:if>

Test
属性值是一个表达式,计算结果转化成布尔值;如果为真则实例化内容模板,否则什么也不做,下例将names
元素中的名字生成一个逗号分隔的列表:

<xsl:template
match="namelist/name">

<xsl:apply-templates/>

<xsl:if
test="not(position()=last())">, </xsl:if>

</xsl:template>

下例将表格每隔一行用黄色显示:

<xsl:template
match="item">

<tr>

<xsl:if test="position() mod 2 =
0">

<xsl:attribute
name="bgcolor">yellow</xsl:attribute>

</xsl:if>

<xsl:apply-templates/>

</tr>

</xsl:template>

9.2


xsl:choose


<!-- Category: instruction -->

<xsl:choose>

<!-- Content: (
xsl:when

+,
xsl:otherwise

?) -->

</xsl:choose>

<xsl:when

test = boolean-expression>

<!-- Content: template -->

</xsl:when>

<xsl:otherwise>

<!-- Content: template -->

</xsl:otherwise>

处理xsl:choose
元素的时候,依次测试每个xsl:when
,只有第一个test
属性表达式求值结果为真的when
的内容模板被实例化;如果都不为真,则实例化otherwise
的内容模板;如果没有otherwise
模板则什么也不创建。比如下例根据有序列表的嵌套深度选择不同的编号格式:

<xsl:template
match="orderedlist/listitem">

<fo:list-item indent-start='2pi'>

<fo:list-item-label>

<xsl:variable name="level"

select="count(ancestor::orderedlist) mod 3"/>

<xsl:choose>

<xsl:when test='$level=1'>

<xsl:number
format="i"/>

</xsl:when>

<xsl:when test='$level=2'>

<xsl:number
format="a"/>

</xsl:when>

<xsl:otherwise>

<xsl:number
format="1"/>

</xsl:otherwise>

</xsl:choose>

<xsl:text>. </xsl:text>

</fo:list-item-label>

<fo:list-item-body>

<xsl:apply-templates/>

</fo:list-item-body>

</fo:list-item>

</xsl:template>

10


排序


<xsl:sort

select = string-expression

lang = { nmtoken }

data-type = { "text" | "number" |
qname-but-not-ncname }

order = { "ascending" | "descending" }

case-order = { "upper-first" | "lower-first"
} />

排序xsl:sort
元素可以出现在xsl:apply-templates
或xsl:for-each
中,xsl:sort
的第一个孩子指定排序主键,第二个指定次重要键,依次类推。如果xsl:apply-templates
或xsl:for-each
元素中出现一个或多个xsl:sort
,则不再按照文档序处理选中的节点,而是根据指定的键排列节点然后依次处理。如果用在xsl:for-each
元素中, xsl:sort
必须是第一个孩子。xsl:apply-templates
和xsl:for-each
实例化模板的时候,当前节点列表包括经过排序的所有待处理节点。

属性select
的值是一个表达式,处理每个节点的时候,以处理的节点为当前节点、没有排序的全部待处理节点作为当前节点列表对这个表达式求值,结果转化为字符串,作为该节点的排序键。Select
属性的默认值为.
,即以当前节点的字符串值作为排序键。

其他属性作为属性值模板处理,用于控制排序。Order
指定按升序(ascending
)还是降序(descending
)排序。Lang
说明按什么语言排序,默认由系统环境决定。data-type
指定字符串的类型:text
表示按照lang
语言习惯的词典序排序,number
说明要转化成数字进行排序,此时不再考虑lang
属性;如果采用其他数据类型也可指定一个QName
;默认值为text
。case-order
取值
upper-first
或lower-first
,表明text
类型的键按照大写字母还是小写字母在前。

比如:

<employees>

<employee>

<name>

<given>James</given>

<family>Clark</family>

</name>

...

</employee>

</employees>

可采用下列模板规则:

<xsl:template
match="employees">

<ul>

<xsl:apply-templates
select="employee">

<xsl:sort
select="name/family"/>

<xsl:sort
select="name/given"/>

</xsl:apply-templates>

</ul>

</xsl:template>

<xsl:template
match="employee">

<li>

<xsl:value-of
select="name/given"/>

<xsl:text> </xsl:text>

<xsl:value-of
select="name/family"/>

</li>

</xsl:template>

11


变量和参数


<!-- Category: top-level-element -->

<!-- Category: instruction -->

<xsl:variable

name = qname

select = expression>

<!-- Content: template -->

</xsl:variable>

<!-- Category: top-level-element -->

<xsl:param

name = qname

select = expression>

<!-- Content: template -->

</xsl:param>

变量是绑定某个值的名称,绑定的值可以是表达式能够返回的任何对象。绑定变量可使用xsl:variable
或xsl:param
元素,差别在于为xsl:param
变量指定的值仅仅是一个默认值,引用参数额模板或样式表被调用时,可使用传递的参数代替默认值。变量绑定元素在样式表树中都有一定的可见区域,在该区域中,对于变量绑定元素本身可见的任何变量绑定都是不可见的,就是说只有最内层的变量可见。

11.1


结果树片段


除了四种基本XPath
数据类型(字符串、数字、Boolean
和节点集)之外,变量为表达式语言引入了一种新的数据类型:结果树片段。结果树片段表示结果树的一部分,相当于只有一个根节点的节点集,但是只允许字符串操作,而不能使用/
、//
和[]
运算符。结果树片段复制到结果树中的时候,所有节点全部复制。只有引用结果树片段类型的变量,或者调用返回结果树片段类型的扩展函数、请求返回结果树片段类型的系统属性,表达式才会返回这种类型的值。

11.2


变量和参数的值


为变量绑定元素赋值有三种方式:select
属性(此时元素的内容必须为空)、指定元素内容模板(没有select
属性,变量的值为模板实例化得到的结果树片段)或者取默认值空字符串(没有select
和内容模板)。如果使用内容模板,则结果树片段中的节点不能有属性和名称空间节点,结果树片段中节点的基准URI
即变量绑定元素的基准URI


如果使用变量引用节点位置,不能用:

<xsl:variable
name="n">2</xsl:variable>...

<xsl:value-of
select="item[$n]"/>

因为变量n
绑定的是一个结果树片段,而不是数字,上述模板将输出第一个item
元素的值。可改为下面的形式:

<xsl:variable
name="n" select="2"/>...

<xsl:value-of
select="item[$n]"/>

或者

<xsl:variable
name="n">2</xsl:variable>...

<xsl:value-of
select="item[position()=$n]"/>

下面的模板将参数值指定为空节点集:

<xsl:param
name="x" select="/.."/>

11.3





xsl:copy-of


中使用变量和参数


<!-- Category: instruction -->

<xsl:copy-of select
= expression />

与xsl:value-of
首先转换成字符串不同, xsl:copy-of
元素直接将结果树片段插入结果树。如果必要属性select

达式计算的结果是一个结果树片段,则将整个片段复制到结果树中。如果是一个节点集,则将所有节点按照文档顺序插入结果树:元素节点的复制包括名称空间节
点、属性节点、孩子结点以及该元素本身;根节点的复制包括所有的孩子但不包括它自身。如果结果既不是结果树片段也不是节点集,则转化成字符串插入结果树。

11.4


顶层变量和参数


顶层变量绑定声明的是全局变量,到处可见。顶层xsl:param
元素为样式表本身声明参数,但XSLT
本身没有定义向样式表传递参数的机制。样式表不能包含相同导入优先级的同名变量绑定。定义变量值的表达式或者模板计算时,上下文节点即处理根节点时所用的上下文节点,当前节点即源文档的根节点,当前节点列表仅包含根节点。如果全局变量的值引用另一个变量,应避免循环引用。

<xsl:variable
name="para-font-size">12pt</xsl:variable>

<xsl:template
match="para">

<fo:block
font-size="{$para-font-size}">

<xsl:apply-templates/>

</fo:block>

</xsl:template>

11.5


模板中的变量和参数


在模板中,xsl:variable
可以出现在任何允许指令的地方,xsl:param
只能出现在xsl:template
的开始位置。绑定对其后的兄弟及其后代都是可见的,但对于变量绑定元素本身不可见。同一模板中的变量绑定不能同名,但可以使用相同的名称覆盖(上层模板或?)顶层的变量绑定。为便于批处理方式处理器的实现,变量一经绑定,其值不再改变。

11.6


向模板传递参数


<xsl:with-param name = qname select =
expression>

<!-- Content: template -->

</xsl:with-param>

元素xsl:with-param
用于向模板传递参数,可用于xsl:call-template
和xsl:apply-templates
。属性name
指定要替换其默认值的参数名称,没有匹配参数名的xsl:with-param
将被忽略。赋值的方法和变量绑定相同,计算select
表达式的上下文和模板调用元素xsl:apply-templates
或xsl:call-template
相同。

<xsl:template
name="numbered-block">

<xsl:param name="format">1.
</xsl:param>

<fo:block>

<xsl:number
format="{$format}"/>

<xsl:apply-templates/>

</fo:block>

</xsl:template>

<xsl:template
match="ol//ol/li">

<xsl:call-template
name="numbered-block">

<xsl:with-param
name="format">a. </xsl:with-param>

</xsl:call-template>

</xsl:template>

12


其它函数


12.1


多个源文档


Function:


node-set

document
(object
, node-set
?)

Document
函数用于访问主源文档之外的XML
文档。

如果第一个参数不是节点集,则转化成字符串作为文档URI
,检索文档并构造源树。如果URI
不包含片段标识符,则返回的节点集中仅包含文档的根节点,否则返回片段标识符所指定的节点。

When the
document

function has exactly one argument and the argument is a
node-set, then the result is the union, for each node in the argument node-set,
of the result of calling the
document

function with the first argument being the
string-value

of the node, and the second argument being a node-set
with the node as its only member. When the
document

function has two arguments and the first argument is a
node-set, then the result is the union, for each node in the argument node-set,
of the result of calling the
document

function with the first argument being the
string-value

of the node, and with the second argument being the
second argument passed to the
document

function.

URI
引用是相对的。使用第二个参数node-set
中第一个节点的基准
URI
来解析绝对URI
。如果没有第二个参数,则默认为样式表中调用document
函数的那个节点。document("")
引用样式表的根节点。

Two documents
are treated as the same document if they are identified by the same URI. The
URI used for the comparison is the absolute URI into which any relative URI was
resolved and does not include any fragment identifier. One root node is treated
as the same node as another root node if the two nodes are from the same
document. Thus, the following expression will always be true:

generate-id(document("foo.xml"))=generate-id(document("foo.xml"))

The
document

function gives rise to the possibility that a node-set
may contain nodes from more than one document. With such a node-set, the
relative document order of two nodes in the same document is the normal
document order

defined by XPath
[XPath]

. The relative document order of two nodes in different
documents is determined by an implementation-dependent ordering of the
documents containing the two nodes. There are no constraints on how the
implementation orders documents other than that it must do so consistently: an
implementation must always use the same order for the same set of documents.

12.2





Key
用于隐含交叉索引。XML
中的ID
、IDREF
和IDREFS
属性用于对XML
文档进行显式的交叉索引,XSLT
提供了XPath id
函数来访问这些属性。但这种机制有不少局限性:ID
属性必须在DTD
中声明,如果采用外部DTD
,只有读入的时候才能识别;一个文档只能包含一组彼此不同的ID
;元素ID
只能作为属性指定;ID
只能是XML
名,不能包含空格;一个元素最多只能有一个ID
。因此有时候XML
文档采用其他的交叉索引结构。

一个key
是一个三元组:节点、键的名称和键值(字符串)。键是ID
的推广,但没有ID
的局限。在样式表中使用xsl:key
元素声明,命名键的值可以在任何适当的地方指定,比如属性、孩子或内容,使用XPath
表达式赋值,键值可以是任何字符串。同一个节点可有多个键,这些键甚至可以同名但值不同。同一个文档中可有多个键名、键值都相同但属于不同节点的键。

<!-- Category: top-level-element -->

<xsl:key name
= qname match = pattern use = expression />

属性name
指定键名,必须是一个QName
。属性match
是一个模式,与其匹配的任何节点都可拥有该键。属性use
是一个表达式,对和模式匹配的每个节点计算一次,将结果作为键值。如果结果是节点集,则该节点拥有多个同名的键,每个键的值分别是节点集中每个节点的字符串值;否则结果转化成字符串作为键值。因此,如果节点x
有一个键y
,值为z
,则必须存在一个xsl:key
元素:

x
和xsl:key
的match
属性匹配;

xsl:key
元素属性name
的值为y


如果use
属性以x
为当前节点、仅含x
的节点列表为当前节点列表,计算得到对象u
,则z
等于u
转化成字符串的值,或者等于u
中每个节点的字符串值。

如果节点和多个xsl:key
元素匹配,所有匹配的xsl:key
元素都会使用。属性use
和match
不能包含变量引用。

Function:


node-set

key


(string, object)

第一个参数指定了键的名称。如果第二个参数是节点集以外的类型则转化成字符串作为键值,返回文档中具有该键且键值为这个字符串的所有节点组成的节点集。如果第二个参数是节点集,相当于指定了多个键值(彼此为或的关系)。

比如,对于声明<xsl:key
name="idkey" match="div" use="@id"/>
,表达式
("idkey",@ref)
相当于id(@ref)
,假设XML
源文档中声明了唯一的ID
属性<!ATTLIST
div id ID #IMPLIED>
而且当前节点的ref
属性没有空格。

假一个描述函数库的文档使用prototype
元素定义函数:

<prototype name="key"
return-type="node-set">

<arg type="string"/>

<arg type="object"/>

</prototype>

并且有一个function
元素引用函数名:

<function>key</function>

可用下面的样式表在引用和定义之间建立超链接:

<xsl:key name="func"
match="prototype" use="@name"/>

<xsl:template match="function">

<b>

<a
href="#{generate-id(key('func',.))}">

<xsl:apply-templates/>

</a>

</b>

</xsl:template>

<xsl:template match="prototype">

<p><a name="{generate-id()}">

<b>Function: </b>

...

</a></p>

</xsl:template>

还可使用key
检索其它文档中的键。比方说,假设文档中有形如<bibref>XSLT</bibref>
的参考资料引用,而另一个XML
文档bib.xml
则包含资料记录<entry
name="XSLT">...</entry>
,可用下面的样式表转换bibref
元素:

<xsl:key name="bib" match="entry"
use="@name"/>

<xsl:template match="bibref">

<xsl:variable
name="name" select="."/>

<xsl:for-each
select="document('bib.xml')">

<xsl:apply-templates select="key('bib',$name)"/>

</xsl:for-each>

</xsl:template>

12.3


数字格式


Function:


string

format-number
(number
, string
, string
?)

函数
format-number

将参数number
中的数字按照第二个参数string
指定的格式转化成字符串,第三个参数用于指定小数格式(否则采用默认小数格式)。格式化字符串采用JDK1.1 DecimalFormat
类定义的语法,不能包含货币符号(#x00A4
)。小数格式必须是QName
,引用decimal-format
元素。

<!--
Category: top-level-element -->

<xsl:decimal-format

name = qname

decimal-separator = char

grouping-separator = char

infinity = string

minus-sign = char

NaN = string

percent = char

per-mille = char

zero-digit = char

digit = char

pattern-separator = char />

属性name
给出了小数格式的名称,如果没有指定name
属性则为默认小数格式。其他属性和JDK 1.1

DecimalFormatSymbols

类中的方法相对应。属性decimal-separator
指定小数部分的分隔符号,默认为“.
”(小数点)。属性percent
指定百分号,默认为%
。per-mille
千分位,默认为Unicode
千分符 (#x2030)
。zero-digit
指定代表零的符号,默认为0


下面两个属性控制格式化模式(字符串)的解释:digit
指定格式化字符串中的数字占位符,默认为#
;pattern-separator
用于将模式划分为两部分,分别用于正数和负数,默认值为;


下面三个属性指定可以出现在格式化结果中的字符或字符串:infinity
定义用于表示无限大的字符串,默认值为Infinity
;NaN
定义表示NaN
值的字符串,默认为NaN
;minus-sign
定义默认的负数符号,缺省值为-


12.4


杂项函数


Function:


node-set

current
()

返回一个节点集,其中只包含当前节点。对于最外层表达式,当前节点一定是上下文节点,因此<xsl:value-of select="current()"/>
和<xsl:value-of select="."/>
是相同的。但是谓词中([]
)中的当前节点通常和上下文节点不一致,比如<xsl:apply-templates
select="//glossary/item[@name=current()/@ref]"/>
将处理glossary
下name
属性与当前节点ref
属性相同的所有item
节点,而不同于<xsl:apply-templates
select="//glossary/item[@name=./@ref]"/>
,后者相当于<xsl:apply-templates
select="//glossary/item[@name=@ref]"/>
,即name
属性和ref
属性值相同的item
节点。模式中不能使用current
函数。

Function:


string

unparsed-entity-uri


(string)

返回指定名称的非解析实体URI
作为当前节点。

Function:


string

generate-id


(node-set?)

生成一个字符串唯一标识参数node-set
中的第一个节点,如果省略参数则默认为当前节点。生成的唯一标识符只能由ASCII
字母或数字组成,并且必须以字母开始。

Function: object system-property(string)


返回指定的系统属性。xsl:version
,处理器实现XSLT
版本号(数字); xsl:vendor
,XSLT
处理器提供商(字符串);xsl:vendor-url
,提供商的主页(字符串)。

13


消息


<!-- Category:
instruction -->

<xsl:message terminate = "yes" |
"no">

<!-- Content: template -->

</xsl:message>

发送一条消息,具体发送方式依赖于XSLT
处理器。Xsl:message
的内容是一个模板,实例化的时候创建一个XML
片段作为消息的内容。如果属性terminate
的值是yes
,发送这条消息后XSLT
处理器应停止处理,默认值为no


实现消息本地化,最好的办法是将某种语言的消息文本集中到一个文件中。比如,假设L
语言的消息存储到/L.xml
文件中:

<messages>

<message
name="problem">A problem was detected.</message>

<message
name="error">An error was detected.</message>

</messages>

样式表可通过下面的办法检索:

<xsl:param name="lang"
select="en"/>

<xsl:variable name="messages"

select="document(concat('resources/', $lang,
'.xml'))/messages"/>

<xsl:template name="localized-message">

<xsl:param
name="name"/>

<xsl:message>

<xsl:value-of select="$messages/message[@name=$name]"/>

</xsl:message>

</xsl:template>

<xsl:template name="problem">

<xsl:call-template name="localized-message"/>

<xsl:with-param
name="name">problem</xsl:with-param>

</xsl:call-template>

</xsl:template>

14


扩展


XSLT
支持两种形式的扩展:扩展元素和扩展函数。

15


退让


<!-- Category:
instruction -->

<xsl:fallback>

<!-- Content: template -->

</xsl:fallback>

通常实例化xsl:fallback
元素什么也不做。但是,如果XSLT
处理器对指令元素执行退让,而指令元素有一个或多个xsl:fallback
孩子,则所有xsl:fallback
孩子的内容必须按照顺序实例化。xsl:fallback
元素的内容是模板。

下列函数可与xsl:choose
或xsl:if
指令结合使用,定义如果某个元素或函数不存在样式表应如何处理。

Function:


boolean

element-available
(string
)

判定是否存在指定的指令。

Function:


boolean

function-available


(string)

判定函数库中是否存在指定的函数。

16 Output


<!-- Category:
top-level-element -->

<xsl:output

method = "xml" | "html" | "text" |
qname-but-not-ncname

version = nmtoken

encoding = string

omit-xml-declaration = "yes" | "no"

standalone = "yes" | "no"

doctype-public = string

doctype-system = string

cdata-section-elements = qnames

indent = "yes" | "no"

media-type = string />

元素xsl:output
用于指定输出格式,只能作为顶层元素出现。属性method
定义了输出结果树的基本方式。如果没有前缀的话,只能是xml
、html
和text
之一。

如果结果树的根节点有元素孩子,而且第一个元素孩子(文档元素)的扩展名包含html
(不论大小写)且没有名称空间URI
,第一个元素孩子之前的所有文本节点都只含空白字符,则默认输出方法为html
,否则默认输出方法为xml


Version
指定output
方法的版本;indent
说明输出结果树的时候是否允许添加空白,只能是yes
或no
;encoding
指定对输出字符序列的编码方法,大小写敏感,必须是IANA
(RFC2278
)注册的字符集或者以X-
开始;media-type
指定数据的MIME
媒体类型,不应包含charset
参数;doctype-system
指定文档类型声明中使用的系统标识符;doctype-public
指定文档类型声明使用的公共标识符;omit-xml-declaration
指定是否输出XML
声明,只能是yes
或no
;standalone
指定是否输出独立文档声明,只能是yes
或no
;cdata-section-elements
指定一组元素名称,文本孩子结点使用CDATA
节输出。

16.1 XML


输出方法


Xml
输出方法将结果树作为良构的XML
一般可解析实体输出,如果结果树只有一个元素节点孩子而没有文本节点孩子,也可看做良构的XML
文档实体。 注意,输出XML
处理器可能需要增加名称空间声明。

Version
属性指定输出结果树使用的XML
版本,默认为1.0


Encoding
指定编码格式,处理器必须支持UTF-8
和UTF-16


属性indent
如果为yes
,可以使结果比较美观,默认值为no


16.2 HTML


输出方法


The html output
method outputs the result tree as HTML; for example,

<xsl:stylesheet version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="html"/>

<xsl:template match="/">

<html>

<xsl:apply-templates/>

</html>

</xsl:template>

...

</xsl:stylesheet>

属性version
的默认值为4.0
。扩展名包含非空名称空间URI
的元素应该作为XML
输出。如果元素扩展名没有名称空间URI
,但是本地名也不是HTML
元素名,则作为非空的行内元素输出。空元素不输出结束标签,如area
、base
、basefont
、br
、col
、frame
、hr, img
、input
、isindex
、link
、meta
和param
。比如样式表中的<br/>
或 <br></br>
应输出<br>
。HTML
元素名称不区分大小写,应该都能正确识别,如BR
、Br
应该都输出没有结束标签的br
。Html
输出方法不能对脚本或样式元素的内容转义,比如<script>if (a < b) foo()</script>
或<script><![CDATA[if (a < b) foo()]]></script>
应该输出<script>if (a < b) foo()</script>
。不能转义属性值中出现的<
字符。Indent
的默认值是yes
。Html
输出方法应该转义URI
属性值中出现的非ASCII
字符。输出处理指令时应用>
代替?>
。以最简形式输出布尔属性值,如<OPTION
selected="selected">
输出<OPTION
selected>
。不能转义属性值中的“&{
”,如<BODY bgcolor='&{{randomrbg}};'>
应输出<BODY bgcolor='&{randomrbg};'>


如果有HEAD
元素,应添加META
元素指定实际使用的字符编码,如<HEAD><META
http-equiv="Content-Type" content="text/html;
charset=EUC-JP">...
。media-type
的默认值是text/html


16.3 Text


输出方法


文本输出方式不对字符进行转义,
media-type
属性的默认值是text/plain


16.4


禁用输出转义


通常为保证输出XML
是良构的,xml
输出方法会对&
和<
(可能还有其他字符)进行转义,但是对xsl:value-of
或xsl:text
元素可通过disable-output-escaping =
‘yes
’禁用输出转义。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: