<xsl:variable>可不是新东西了,它在XSLT1.0中也有着很广泛的应用。但我看到有些文章写到了1.0和2.0的不同,但可惜的是,他们写的代码根本和他们的说法相矛盾。
---------------------------
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 >
< 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 >
< 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 >
< 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)
---------------------------
---------------------------
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)
---------------------------