<xsl:variable>可不是新东西了,它在XSLT1.0中也有着很广泛的应用。但我看到有些文章写到了1.0和2.0的不同,但可惜的是,他们写的代码根本和他们的说法相矛盾。
以下引用自:
[url]http://www.oracle.com/technology/global/cn/pub/articles/wang_xslt.html[/url]
---------------------------
XML文档:
<CATALOG>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
<CD>
<TITLE>Hide your heart</TITLE>
<ARTIST>Bonnie Tylor</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>CBS Records</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1988</YEAR>
</CD>
<CD>
<TITLE>Still got the blues</TITLE>
<ARTIST>Gary More</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>Virgin records</COMPANY>
<PRICE>10.20</PRICE>
<YEAR>1990</YEAR>
</CD>
<CD>
<TITLE>This is US</TITLE>
<ARTIST>Gary Lee</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>Virgin records</COMPANY>
<PRICE>12.20</PRICE>
<YEAR>1990</YEAR>
</CD>
</CATALOG>
特性 3:临时树
临时树是在 XSLT 2.0 中推出的另一项新结构。与 XSLT 1.0 将 XSL 转换的中间结果和 XSL 变量表示为字符串不同,XSLT 2.0 将由
<xsl:variable>、<xsl:param>
或
<xsl:with-param>
元素构造的中间结果和 XSL 变量存储为一组称为临时树的文档节点。
使用临时树,您可以使用 XPath 表达式来计算变量或参数的内容,并把 XSL 处理模块化。当使用模板或者从 XSL 变量或模板参数中提取数据时,这种方法提供了很大的灵活性。例如,如下所示,将目录变量设为选择 1988 年以后发行的所有 CD。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:variable name="catalog" select="//CD[number(YEAR)>=1988]"/>
<xsl:template match="/">
<Expensive>
<xsl:apply-templates select="$catalog[number(PRICE)>10]"/>
</Expensive>
<Cheap>
<xsl:apply-templates select="$catalog[number(PRICE) < 10]"/>
</Cheap>
</xsl:template>
<xsl:template match="*">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
随后可以对所选节点作进一步的分类,将价格等于或高于 10 美元的 CD 归类为高价 CD,将价格低于 10 美元的 CD 归类为廉价 CD。如果没有临时树特性,则
<xsl:apply-templates select="$catalog[number(PRICE) < 10]"/>
是无效的,并且无法访问您先前在创建
$catalog
变量时所选择的数据。
--------------
且不论它的XSLT有一个很低级的错误,就是select中使用了“<”(很明显作者根本没有运行过这段代码),它所描述的真的是1.0和2.0的区别吗?
更正它的错误,利用SAXON运行一下,得到结果:
<
?xml version='1.0' ?
><
Expensive
>
<
CD
>
<
TITLE
>Still got the blues
<
/TITLE
>
<
ARTIST
>Gary More
<
/ARTIST
>
<
COUNTRY
>UK
<
/COUNTRY
>
<
COMPANY
>Virgin records
<
/COMPANY
>
<
PRICE
>10.20
<
/PRICE
>
<
YEAR
>1990
<
/YEAR
>
<
/CD
>
<
CD
>
<
TITLE
>This is US
<
/TITLE
>
<
ARTIST
>Gary Lee
<
/ARTIST
>
<
COUNTRY
>UK
<
/COUNTRY
>
<
COMPANY
>Virgin records
<
/COMPANY
>
<
PRICE
>12.20
<
/PRICE
>
<
YEAR
>1990
<
/YEAR
>
<
/CD
><
/Expensive
><
Cheap
>
<
CD
>
<
TITLE
>Hide your heart
<
/TITLE
>
<
ARTIST
>Bonnie Tylor
<
/ARTIST
>
<
COUNTRY
>UK
<
/COUNTRY
>
<
COMPANY
>CBS Records
<
/COMPANY
>
<
PRICE
>9.90
<
/PRICE
>
<
YEAR
>1988
<
/YEAR
>
<
/CD
><
/Cheap
>
我们试着把version="2.0" 改成version="1.0",注意处理器也要换成老的XALAN。
我们可以得到同样的结果。
这证明那位ORACLE的经理的说法是有问题了。
那么,1.0和2.0在临时结果树问题上到底是否存在区别呢?
当然是有区别了。
它们的区别在于,当变量的赋值形式为content赋值时,1.0和2.0才有这种区别。
举例来说:
XSL文档:
<
?xml version='1.0'?
><
xsl:stylesheet
version=
"2.0"
xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform"
>
<
xsl:template
match=
"/"
>
<
xsl:variable
name=
"catalog"
>
<
cd
>
<
title
>the song of sping
<
/title
>
<
price
>12.90
<
/price
>
<
quantity
>18
<
/quantity
>
<
/cd
>
<
/xsl:variable
>
<
xsl:apply-templates
select=
"$catalog/cd"
/
><
/xsl:template
><
/xsl:stylesheet
>
得到输出结果:
the song of sping12.9018
---------------------------
换作1.0.:
<
?xml version='1.0'?
><
xsl:stylesheet
version=
"1.0"
xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform"
>
<
xsl:template
match=
"/"
>
<
xsl:variable
name=
"catalog"
>
<
cd
>
<
title
>the song of sping
<
/title
>
<
price
>12.90
<
/price
>
<
quantity
>18
<
/quantity
>
<
/cd
>
<
/xsl:variable
>
<
xsl:apply-templates
select=
"$catalog/cd"
/
><
/xsl:template
><
/xsl:stylesheet
>
注意processor换回老的。
Stylus Studio 2007 给出错误
---------------------------
java.lang.ClassCastException: org.apache.xpath.objects.XRTreeFrag cannot be cast to org.apache.xpath.objects.XNodeSet
URL:
file:///e:/tmp/catalog1.xsl
Line:12
Col: 45
Jump to location?
---------------------------
是(Y) 否(N)
---------------------------
本文出自 51CTO.COM技术博客
相关资源:垃圾分类数据集及代码