﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Bobby-随笔分类-XSLT</title><link>http://www.blogjava.net/bobby/category/34797.html</link><description>幸福的人创造幸福的世界！</description><language>zh-cn</language><lastBuildDate>Wed, 24 Sep 2008 04:05:38 GMT</lastBuildDate><pubDate>Wed, 24 Sep 2008 04:05:38 GMT</pubDate><ttl>60</ttl><item><title>XSL语法介绍  </title><link>http://www.blogjava.net/bobby/archive/2008/09/24/230823.html</link><dc:creator>bobby</dc:creator><author>bobby</author><pubDate>Wed, 24 Sep 2008 02:19:00 GMT</pubDate><guid>http://www.blogjava.net/bobby/archive/2008/09/24/230823.html</guid><wfw:comment>http://www.blogjava.net/bobby/comments/230823.html</wfw:comment><comments>http://www.blogjava.net/bobby/archive/2008/09/24/230823.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bobby/comments/commentRss/230823.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bobby/services/trackbacks/230823.html</trackback:ping><description><![CDATA[<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size: 18pt">XSL语法介绍&nbsp;</span> </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　&nbsp; </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 首先注意到的是，XSL文件本身即是一份 XML文件，所以在XSL文件的开头，一样有和XML文件相同的声明。W3C这个XML的标准机构为XSL定义了很多标记（元素），XSL文件就是这些标记和HTML标记的组合。在XSL文件中，必须有如下一行的代码： </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 ＜xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"＞ </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 这里，xsl:stylesheet是XSL文件的根元素，在根元素中包含了所有的排版样式，样式表就是由这些排版样式组合成的；xmlns:xsl="http://www.w3.org/TR/WD-xsl"这一句主要用来说明该XSL样式表是使用W3C所制定的XSL，设定值就是XSL规范所在的URL地址。 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 实际上，这里"http://www.w3.org/TR/WD-xsl"就是一个名字空间（namespace），我们在上面关于XML Schema语法介绍的时候已经进行过介绍。这是一个标准的名字空间。"stylesheet"，"template"，"for-each"等等关键字都是这个名字空间所定义的。 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 当然在xsl:stylesheet还可以设定其他的属性，其他的属性有： </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　　 1． default-space：决定是否保留XML文件中的空白，仅当值为"default"时保留。 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　　 2． indent-result：决定是否保留XSL文件中的空白，值为"yes"时保留。 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　　 3． language：设定在XSL文件中使用的脚本语言。 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 然后，我们在上面的代码中看到有如下的代码： </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 ＜xsl:template match="/"＞ <br />
　　　 &#8230;&#8230;&#8230; <br />
　　 ＜/xsl:template＞ </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 这里实际上是表示了XSL解析器对XML文档的处理过程，它从根节点（由match="/"决定，这里"/"就表示根节点）开始，对XML文档进行遍历，并根据具体的代码从XML文档中取出相关的内容。这里关于属性match的取值是一个比较复杂的问题。它实际上表示的含义是从XML文档中取出一个特定的节点集合（XML文档可以被看成一个树的结构，这个在后面关于XML解析器分析中有详细的介绍）。这里，我们通过几个简单的例子来说明属性match的取值。 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 比如下面一行代码： </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 ＜xsl:template match="/"＞ </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 这行代码的意思是告诉XSL解析程序，当前需要处理的节点是根节点下的内容（用"/"来表示根节点），其实这里的match值内容的编写是要符合XPath的语意。关于XPath我们在后面的章节中会进行详细的介绍。 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 再举一个例子： </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 ＜xsl:template match="shoppingcart/item"＞ </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 这行代码要匹配的是shoppingcart元素下的item元素。而不管shoppingcart在XML文档结构树下的哪一个位置。比如XML文档的其中一段是这样的。 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 ＜shoppingcart＞ <br />
　　 ＜item＞ <br />
　　 ＜itemNo＞3333＜/itemNo＞ <br />
　　 ＜itemName＞屠龙刀＜/itemName＞ <br />
　　 ＜/item＞ <br />
　　 ＜item＞ <br />
　　 ＜itemNo＞4444＜/itemNo＞ <br />
　　 ＜itemName＞离别钩＜/itemName＞ <br />
　　 ＜/item＞ <br />
　　 ＜/shoppingcart＞ </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 那么它匹配的内容就是 <br />
　　　 ＜item＞ <br />
　　　 ＜itemNo＞3333＜/itemNo＞ <br />
　　　 ＜itemName＞屠龙刀＜/itemName＞ <br />
　　　 ＜/item＞ <br />
　　　 ＜item＞ <br />
　　　 ＜itemNo＞4444＜/itemNo＞ <br />
　　　 ＜itemName＞离别钩＜/itemName＞ <br />
　　　 ＜/item＞ </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 而下面这个例子： </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 ＜xsl:template match="/shoppingcart/item"＞ </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">表示只匹配XML文档根节点下的shoppingcart这个节点下的所有item元素。也就是说如果shoppingcart不是直接在根节点下的，它就不符合这个匹配条件。 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 再看一个例子： </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 ＜xsl:template match="price[@unit='USD']"＞ </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">这个例子说明要匹配的是这样的节点：一个带unit属性的元素price，而且unit的值必须为"USD"。比如一段XML代码是这样的。 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 ＜price＞ <br />
　　　 ＜unit＞USD＜/unit＞ <br />
　　　 ＜amount＞100＜/amount＞ <br />
　　 ＜/price＞ <br />
　　 ＜price＞ <br />
　　　 ＜unit＞RMB＜/unit＞ <br />
　　　 ＜amount＞300＜/amount＞ <br />
　　 ＜/price＞ </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 那么它匹配的内容就是： </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 ＜price＞ <br />
　　　 ＜unit＞USD＜/unit＞ <br />
　　　 ＜amount＞100＜/amount＞ <br />
　　 ＜/price＞ </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 实际上，存在许多各种符号用来表示匹配规则，我们在XPath语法介绍中会详细涉及到。现在知道这么一个大概的概念就可以了。 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 我们用＜xsl:template match="具体匹配表达式"＞这条语句找到了一些节点集合以后，我们就要从这个集合中找到特定的元素或者元素属性的值，那么采用什么语句呢？就是用xsl:value-of select = ""这样的语句来寻找特定的内容。 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 比如下面的例子中＜xsl:value-of select="名称"/＞这行代码就是表示定位XML文档中的名称元素的内容。在指定集合中可能存在多个名字元素，如果我们需要把它们一一列举出来进行处理的话，就需要用到语句xsl:for-each select = ""，注意这里涉及到一个作用范围的概念，也就是说xsl:for-each select = ""这条语句是在一个指定的集合空间中执行的。比如上面例子中如下的代码 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 这里的＜xsl:for-each select="词语"＞是在＜xsl:template match="网络用语集合"＞所指定的集合空间里面寻找元素"词语"的。 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 同时，我们需要注意的是上面的代码中，出现了一条语句 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　　 ＜xsl:apply-templates select="网络用语集合" /＞ </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 它表示什么意思呢，它实际上相当于C++中的一个过程调用，当XSL解析器执行到该语句的时候，它就会在代码中寻找以＜?xml:namespace prefix = xsl /＞＜xsl:template match="网络用语集合"＞开头的代码，所以在上面的例子程序中，以下的代码可以看成是过程的实现。 </span></span></p>
<p><br />
<span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 把看成是一个过程调用，把＜xsl:template match="网络用语集合"＞ </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 &#8230;&#8230;. <br />
　　 ＜/xsl:template＞ </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 看成是过程的实现，有助于我们对XSL解析器执行过程的理解。这里match="网络用语集合"可以理解为是传递给过程的参数，它表示过程实现体的集合范围是该match所匹配的节点集合空间（"网络用语集合"）。 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 如果我们要对表格中的元素进行排序该什么办呢？比如说，在上面的例子中，我们需要按照名称进行排序。很简单对，改写为如下的形式即可： </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 ＜xsl:for-each select="词语" order-by="+名称"＞，其中"+"表示按降序排列；"-"表示按升序排列。"order-by"是XSL语法中的关键字。 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 如果我们只想在列表中取出某几行该怎么操作呢？比如我们只想取出名称为"恐龙"的行，见下面的代码： </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 这里有一个新的句法为：＜xsl:template match="网络用语集合"＞ <br />
　　 ＜table Border="1"＞ <br />
　　　 ＜xsl:for-each select="词语" order-by="-名称"＞ <br />
　　　 ＜xsl:if test=".[名称='恐龙']"＞ <br />
　　　 ＜tr＞ <br />
　　　　 ＜td＞＜xsl:value-of select="名称"/＞＜/td＞ <br />
　　　　 ＜td＞＜xsl:value-of select="含义"/＞＜/td＞ <br />
　　　 ＜/xsl:if＞ <br />
　　　 ＜/xsl:for-each＞ <br />
　　 ＜/table＞ <br />
　　 ＜/xsl:template＞ </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">&nbsp;</span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 它表示如果".[名称='恐龙']"为真（TRUE）的话，就执行该段里面的语句，要是为假（FALSE）的话就不执行。它和C++中的if语句的概念基本是一样的。 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 前面我们用＜xsl:value-of select=""/＞取出的都是一个元素的值，但是我们要取出元素某一个属性的值该怎么做呢？采用下面的形式： </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 ＜xsl:value-of select="元素名称/@属性名称"/＞ </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 比如一段XML代码是这样的： </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 ＜王朔 网址="www.wangshuo.com"＞知名作家加著名评论家王朔先生的地方＜/王朔＞ </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 我们可以用＜xsl:value-of select="王朔/@网址"/＞来得到值"www.wangshuo.com"。 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 以上包括了XSL的大多数基本的语法，更加详细和完整的介绍需要参看W3C相关的最新的文档，可以在WWW.W3C.ORG/TR下找到。 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 根据上面的分析，我们可以看到XSL实际上采用的是一种转换的思想，它最终将XML文档转换为另一种可用于输出的文档，而CSS则没有任何转换动作，在整个过程中没有任何新码产生。 另外，在XSL中90%的样式规定在CSS中都有定义，但仍然有一些效果是CSS无法描述的，必须使用XSL不可。这些功能包括文本的置换、根据文本内容决定显示方式、文档内容排序等，都是XSL所独有的。再者，XSL遵从XML的语法，而CSS的语法自成体系。 </span></span></p>
<p><span style="font-family: Lucida Console"><span style="font-size: 12pt">　　 选择样式单还要考虑不同浏览器对样式单的支持程度。目前IE5与Netscape的最新版本都支持CSS，但支持的程度都有限。至今为止，IE5尚不能完全支持CSS1，即便是支持的部分也存在很多错误，对于CSS2也只提供部分支持。Netscape在对CSS的支持上已经优于IE5，它采用新一代的Raptor/Gecko引擎技术，已经能够完全支持CSS1，但对CSS2的支持计划尚不明朗。而对XSLT而言，只有IE5支持，Netscape5并不支持。 <br />
&nbsp;<br />
</span></span></p>
<img src ="http://www.blogjava.net/bobby/aggbug/230823.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bobby/" target="_blank">bobby</a> 2008-09-24 10:19 <a href="http://www.blogjava.net/bobby/archive/2008/09/24/230823.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XSLT</title><link>http://www.blogjava.net/bobby/archive/2008/09/24/230813.html</link><dc:creator>bobby</dc:creator><author>bobby</author><pubDate>Wed, 24 Sep 2008 01:48:00 GMT</pubDate><guid>http://www.blogjava.net/bobby/archive/2008/09/24/230813.html</guid><wfw:comment>http://www.blogjava.net/bobby/comments/230813.html</wfw:comment><comments>http://www.blogjava.net/bobby/archive/2008/09/24/230813.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bobby/comments/commentRss/230813.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bobby/services/trackbacks/230813.html</trackback:ping><description><![CDATA[<span style="font-size: 12pt"><span style="font-family: Tahoma">&nbsp; </span></span>
<p style="text-indent: 21pt"><span style="font-size: 12pt"><span style="font-family: Tahoma">XSLT <span style="font-family: 宋体">是什么类型的语言，其用途是什么，为什么要这样设计它？这些问题可以有许多不同的答案，初学者往往会感到困惑，因为这种语言与他们以前习惯使用的语言之间有很大差别。本文尝试说明</span> XSLT<span style="font-family: 宋体">。本文并不试图教您编写</span> XSLT <span style="font-family: 宋体">样式表，它将说明这种语言的起源，它擅长什么，以及您为什么应该使用它。</span> <br />
<br />
</span></span></p>
<p><span style="font-size: 12pt"><span style="font-family: Tahoma"><span style="font-family: 宋体">什么是</span> XSLT<span style="font-family: 宋体">？</span> <br />
XSLT <span style="font-family: 宋体">语言由万维网联盟</span> (W3C) <span style="font-family: 宋体">定义，并且该语言的</span> 1.0 <span style="font-family: 宋体">版本在</span> 1999 <span style="font-family: 宋体">年 11 <span style="font-family: 宋体">月</span> 16 </span><span style="font-family: 宋体">日作为</span>&#8220;<span style="font-family: 宋体">推荐书</span>&#8221;<span style="font-family: 宋体">发布（请参阅参考资料）。我已经在拙作</span> XSLT Programmers' Reference <span style="font-family: 宋体">中提供了全面的规范和用户指南，因此我不打算在本文中涵盖相同内容。确切地讲，本文的目的只是使读者理解</span> XSLT <span style="font-family: 宋体">适合大规模事物的哪些位置。</span> <br />
<br />
XSLT <span style="font-family: 宋体">的角色</span> <br />
XSLT <span style="font-family: 宋体">的最初目的是将信息内容与</span> Web <span style="font-family: 宋体">显示分离。如其最初定义那样，</span>HTML <span style="font-family: 宋体">通过按抽象概念（如段落、重点和编号列表）定义显示来实现设备独立性。随着</span> Web <span style="font-family: 宋体">变得越来越商业化，出版人希望其输出质量能达到与印刷品相同的质量。这逐渐导致越来越多地使用具体显示控件，如页面上材料的明确字体和绝对位置。然而不幸的是完全可以预料其副作用，即将相同的内容传递到替代设备，如数字电视机和</span> WAP <span style="font-family: 宋体">电话（印刷业的行话再现效果）将会变得日益困难。</span> <br />
<br />
<span style="font-family: 宋体">由于吸收了印刷业使用</span> SGML <span style="font-family: 宋体">的经验，在</span> 1998 <span style="font-family: 宋体">年初定义了一种标记语言</span> XML<span style="font-family: 宋体">，它用于表示独立于显示的结构化内容。与</span> HTML <span style="font-family: 宋体">使用一组固定概念（如段落、列表和表）不同，</span>XML <span style="font-family: 宋体">标记中使用的标记完全是用户定义的，其用意是这些标记应该与所关注的对象（如人、地点、价格和日期）相关。尽管</span> HTML <span style="font-family: 宋体">中的元素本质上都是印刷样式（虽然处于抽象级别），而</span> XML <span style="font-family: 宋体">的目标是元素应该描述实际对象。例如，清单</span> 1 <span style="font-family: 宋体">显示了表示足球锦标赛结果的</span> XML <span style="font-family: 宋体">文档。</span> <br />
<br />
<span style="font-family: 宋体">清单</span> 1. <span style="font-family: 宋体">表示足球锦标赛结果的</span> XML <span style="font-family: 宋体">文档</span> <br />
&lt;results group="A"&gt; <br />
&lt;match&gt; <br />
&lt;date&gt;10-Jun-1998&lt;/date&gt; <br />
&lt;team score="2"&gt;Brazil&lt;/team&gt; <br />
&lt;team score="1"&gt;Scotland&lt;/team&gt; <br />
&lt;/match&gt; <br />
&lt;match&gt; <br />
&lt;date&gt;10-Jun-1998&lt;/date&gt; <br />
&lt;team score="2"&gt;Morocco&lt;/team&gt; <br />
&lt;team score="2"&gt;Norway&lt;/team&gt; <br />
&lt;/match&gt; <br />
&lt;match&gt; <br />
&lt;date&gt;16-Jun-1998&lt;/date&gt; <br />
&lt;team score="1"&gt;Scotland&lt;/team&gt; <br />
&lt;team score="1"&gt;Norway&lt;/team&gt; <br />
&lt;/match&gt; <br />
&lt;match&gt; <br />
&lt;date&gt;16-Jun-1998&lt;/date&gt; <br />
&lt;team score="3"&gt;Brazil&lt;/team&gt; <br />
&lt;team score="0"&gt;Morocco&lt;/team&gt; <br />
&lt;/match&gt; <br />
&lt;match&gt; <br />
&lt;date&gt;23-Jun-1998&lt;/date&gt; <br />
&lt;team score="1"&gt;Brazil&lt;/team&gt; <br />
&lt;team score="2"&gt;Norway&lt;/team&gt; <br />
&lt;/match&gt; <br />
&lt;match&gt; <br />
&lt;date&gt;23-Jun-1998&lt;/date&gt; <br />
&lt;team score="0"&gt;Scotland&lt;/team&gt; <br />
&lt;team score="3"&gt;Morocco&lt;/team&gt; <br />
&lt;/match&gt; <br />
&lt;/results&gt; <br />
<br />
<br />
<br />
<br />
<span style="font-family: 宋体">如果要通过</span> Web <span style="font-family: 宋体">浏览器显示这些足球赛的结果，不要指望系统会产生合理的布局。需要其它一些机制来告诉系统如何在浏览器屏幕、电视机、</span>WAP <span style="font-family: 宋体">电话或真正在纸张上显示数据。这就是使用样式表的目的。样式表是一组说明性的规则，它定义了应如何表示源文档中标记标识的信息元素。</span> <br />
<br />
W3C <span style="font-family: 宋体">已经定义了两个系列的样式表标准。第一个是在</span> HTML <span style="font-family: 宋体">中广泛使用的</span> CSS<span style="font-family: 宋体">（级联样式表），当然它也可以在</span> XML <span style="font-family: 宋体">中使用。例如，可以使用</span> CSS <span style="font-family: 宋体">来表示何时显示发票，应支付的总额应该用</span> 16 <span style="font-family: 宋体">点</span> Helvetica <span style="font-family: 宋体">粗体字显示。但是，</span>CSS <span style="font-family: 宋体">不能执行计算、重新整理或排序数据、组合多个源码中的数据或根据用户或会话的特征个性化显示的内容。在这个足球赛结果的例子中，</span>CSS <span style="font-family: 宋体">语言（即使是最新版本</span> CSS2<span style="font-family: 宋体">，尚未在产品中完全实现）的功能还不够强大，不能处理这项任务。由于这些原因，</span>W3C <span style="font-family: 宋体">已着手开发更强大的样式表语言</span> XSL<span style="font-family: 宋体">（可扩展样式表语言），并采纳了</span> SGML <span style="font-family: 宋体">社区中开发的</span> DSSSL<span style="font-family: 宋体">（文档样式、语义和规范语言）中许多好的构思。</span> <br />
<br />
<span style="font-family: 宋体">在</span> XSL <span style="font-family: 宋体">的开发过程中（这在</span> DSSSL <span style="font-family: 宋体">中已有所预示），发现在准备</span> XML <span style="font-family: 宋体">文档以备显示的过程中执行的任务可以分成两个阶段：转换和格式化。转换是将一个</span> XML <span style="font-family: 宋体">文档（或其内存中的表示法）转换成另一个</span> XML <span style="font-family: 宋体">文档的过程。格式是将已转换的树状结构转换成两维图形表示法或可能是一维音频流的过程。</span>XSLT <span style="font-family: 宋体">是为控制第一阶段</span>&#8220;<span style="font-family: 宋体">转换</span>&#8221;<span style="font-family: 宋体">而开发的语言。第二阶段</span>&#8220;<span style="font-family: 宋体">格式化</span>&#8221;<span style="font-family: 宋体">的开发工作还是进行中。但实际上，大多数人现在使用</span> XSL <span style="font-family: 宋体">将</span> XML <span style="font-family: 宋体">文档转换成</span> HTML<span style="font-family: 宋体">，并使用</span> HTML <span style="font-family: 宋体">浏览器作为格式化引擎。这是可行的，因为</span> HTML <span style="font-family: 宋体">实际上只是</span> XML <span style="font-family: 宋体">词汇表的一个示例，而</span> XSLT <span style="font-family: 宋体">可以使用任何</span> XML <span style="font-family: 宋体">词汇表作为其目标。</span> <br />
<br />
<span style="font-family: 宋体">将转换成一种语言和格式化成另一种语言这两个操作分离经证实的确是一种好的决策，因为转换语言的许多应用程序经证明无法向用户显示文档。随着</span> XML <span style="font-family: 宋体">日益广泛地用作电子商务中的数据互换语法，对于应用程序将数据从一个</span> XML <span style="font-family: 宋体">词汇表转换成另一个</span> XML <span style="font-family: 宋体">词汇表的需求也在不断增加。例如，某个应用程序可能从电视收视指南中抽取电视节目的细节，并将它们插入按次付费客户的月帐单中。同样，还有许多实用的数据转换，在这些转换中源词汇表和目标词汇表是相同的。它们包括数据过滤，以及商务操作，如施行涨价。因此，随着在系统中开始越来越多地以</span> XML <span style="font-family: 宋体">语法的形式使用数据，</span>XSLT <span style="font-family: 宋体">就逐渐成为由于处理这些数据的随处可见的高级语言。</span> <br />
<br />
<span style="font-family: 宋体">在拙作中，我做了这样一个比喻：</span>XSLT <span style="font-family: 宋体">与</span> XML <span style="font-family: 宋体">的关系，就好象</span> SQL <span style="font-family: 宋体">与表格化数据的关系一样。关系模型的强大功能并非来自用表存储数据的思想，而是源于</span> SQL <span style="font-family: 宋体">中可行的基于关系运算的高级数据操作。同样，</span>XML <span style="font-family: 宋体">的层次化数据模型对应用程序开发者的帮助实际上也非常小。正是因为</span> XSLT <span style="font-family: 宋体">作为</span> XML <span style="font-family: 宋体">数据的高级操作语言提供了如此强大的功能。</span> <br />
<br />
XSLT <span style="font-family: 宋体">作为语言</span> <br />
<span style="font-family: 宋体">就某些方面而言，</span>XSLT <span style="font-family: 宋体">作为一种语言来说是非常古怪的。我不打算在本文中讨论已做出的设计决策的基本原理，尽管可以通过它们在逻辑上追溯到语言设计者确定的对</span> XSLT <span style="font-family: 宋体">的要求。</span><br />
<br />
<span style="font-family: 宋体">以下概述了</span> XSLT <span style="font-family: 宋体">语言的部分主要特性。</span> <br />
<br />
XSLT <span style="font-family: 宋体">样式表是一个</span> XML <span style="font-family: 宋体">文档。通过使用</span> XML <span style="font-family: 宋体">的尖括号标记语法来表示文档的结构。这种语法在某种程度上是比较笨拙的，而此决策可以使该语言变得更罗嗦。但是，它确实有好处。它表示可以自动使用</span> XML <span style="font-family: 宋体">的所有词汇设备（例如，</span>Unicode <span style="font-family: 宋体">字符编码和转义，使用外部实体等等）。它表示很容易使</span> XSLT <span style="font-family: 宋体">样式表变成转换的输入或输出，使该语言可以作用于自身。它还使将期望的</span> XML <span style="font-family: 宋体">输出块嵌入样式表变得很容易。实际上，许多简单的样式表基本上可以写作期望输出文档的模板，并且可以将一些特殊指令嵌入文本中，以便插入输入中的变量数据或计算某个值。这就使</span> XSLT <span style="font-family: 宋体">在这个简单的级别上非常类似于许多现有的专用</span> HTML <span style="font-family: 宋体">模板语言。</span> <br />
<br />
<span style="font-family: 宋体">基本处理范例是模式匹配。在这方面，</span>XSLT <span style="font-family: 宋体">继承了文本处理语言（如</span> Perl<span style="font-family: 宋体">）的传统，这种传统可以一直追溯到</span> 1960 <span style="font-family: 宋体">年代的语言，如</span> SNOBOL<span style="font-family: 宋体">。</span>XSLT <span style="font-family: 宋体">样式表包括一组模板规则，每条规则都使用以下方式：</span>&#8220;<span style="font-family: 宋体">如果在输入中遇到此条件，则生成下列输出。</span>&#8221;<span style="font-family: 宋体">规则的顺序是无关紧要的，当有几条规则匹配同一个输入时，将应用冲突解决算法。然而，</span>XSLT <span style="font-family: 宋体">与串行文本处理语言的不同之处是</span> XSLT <span style="font-family: 宋体">对输入并非逐行进行处理。实际上，</span>XSLT <span style="font-family: 宋体">将输入</span> XML <span style="font-family: 宋体">文档视为树状结构，每条模板规则都适用于树中的一个节点。模板规则本身可以决定下一步处理哪些节点，因此不必按输入文档的原始顺序来扫描输入。</span> <br />
<br />
XSLT <span style="font-family: 宋体">处理器的操作</span> <br />
XSLT <span style="font-family: 宋体">处理器使用树状结构作为其输入，并生成另一个树状结构作为输出。</span><br />
<br />
<span style="font-family: 宋体">常常通过对</span> XML <span style="font-family: 宋体">文档进行语法分析来生成输入树状结构，而输出树状结构通常被串行化到另一个</span> XML <span style="font-family: 宋体">文档中。但</span> XSLT <span style="font-family: 宋体">处理器本身操作的是树状结构，而不是</span> XML <span style="font-family: 宋体">字符流。这个概念最初给许多用户的感觉是不切实际的，结果却对理解如何执行更复杂的转换起了关键作用。首先，它表示</span> XSLT <span style="font-family: 宋体">处理器可以理解源文档中与树状结构无关的特殊之处。例如，无论属性是包括在单引号中还是在双引号中，都不可能应用不同的处理，因为会将这两种形式视为同一个基本文档的不同表示方法。更深入地看，它表示处理输入元素或生成输出元素是一个原子操作。不可能将处理元素的开始标记和结束标记分成单独的操作，因为一个元素会自动表示成树模型的单节点。</span> <br />
<br />
XSLT <span style="font-family: 宋体">使用叫作</span> XPath <span style="font-family: 宋体">的子语言来引用输入树中的节点。</span>XPath <span style="font-family: 宋体">本质上是与具有层次结构的</span> XML <span style="font-family: 宋体">数据模型相匹配的查询语言。它可以通过按任何方向浏览树来选择节点，并根据节点的值和位置应用谓词。它还包括用于基本字符串处理、数字计算和布尔代数的工具。例如，</span>XPath <span style="font-family: 宋体">表达式</span> ../@title <span style="font-family: 宋体">选择当前节点的父代元素的标题属性。</span>XPath <span style="font-family: 宋体">表达式用于选择要进行处理的输入节点、在条件处理期间测试条件，以及计算值以便插入结果树中。模板规则中还使用了</span> XPath <span style="font-family: 宋体">表达式的简化形式</span>&#8220;<span style="font-family: 宋体">模式</span>&#8221;<span style="font-family: 宋体">来定义特定模板规则适用于哪些节点。</span>XPath <span style="font-family: 宋体">在单独的</span> W3C <span style="font-family: 宋体">推荐书中定义，它允许使用在其它上下文中再使用的查询语言，特别是用于定义扩展超链接的</span> XPointer<span style="font-family: 宋体">。</span> <br />
<br />
XSLT <span style="font-family: 宋体">以传统语言（如</span> Lisp<span style="font-family: 宋体">、</span>Haskell <span style="font-family: 宋体">和</span> Scheme<span style="font-family: 宋体">）中的功能性编程的概念为基础。样式表由模板组成，这些模板基本上是单一功能</span> -- <span style="font-family: 宋体">每个模板将输出树的一部分定义成一部分输入树的功能，并且不产生副作用。使用无副作用的规则受到严格控制（除了转义成用类似</span> Java <span style="font-family: 宋体">的语言编写的外部代码）。</span>XSLT <span style="font-family: 宋体">语言允许定义变量，但不允许现有变量更改它的值</span> -- <span style="font-family: 宋体">即没有赋值语句。这个策略使许多新用户感到困惑，其目的是为了允许逐步应用样式表。其原理是如果语言没有副作用，那么对输入文档做很小的改动时，不必从头执行整个转换就应该可以计算出对输出文档的最后更改。目前必须说这只是理论上的可能，任何现有</span> XSLT <span style="font-family: 宋体">处理器还不能实现。（注：虽然</span> XSLT <span style="font-family: 宋体">以功能性编程概念为基础，但它还不是一个完整的功能性编程语言，因为它缺少将函数当作一级数据类型进行处理的能力。）</span> <br />
<br />
<span style="font-family: 宋体">示例样式表</span> <br />
<span style="font-family: 宋体">在这个阶段，使用示例会使语言变得更清楚。清单</span> 2 <span style="font-family: 宋体">显示了列出足球赛结果的简单样式表。</span> <br />
<br />
<span style="font-family: 宋体">清单</span> 2. <span style="font-family: 宋体">足球赛结果的基本样式表</span> <br />
<br />
&lt;xsl:transform <br />
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&gt; <br />
<br />
&lt;xsl:template match="results"&gt; <br />
&lt;html&gt; <br />
&lt;head&gt;&lt;title&gt; <br />
Results of Group &lt;xsl:value-of select="@group"&gt; <br />
&lt;/title&gt;&lt;/head&gt; <br />
&lt;body&gt;&lt;h1&gt; <br />
Results of Group &lt;xsl:value-of select="@group"&gt; <br />
&lt;/h1&gt; <br />
&lt;xsl:apply-templates&gt; <br />
&lt;/body&gt;&lt;/html&gt; <br />
&lt;/xsl:template&gt; <br />
<br />
&lt;xsl:template match="match"&gt; <br />
&lt;h2&gt; <br />
&lt;xsl:value-of select="team[1]"&gt; versus &lt;xsl:value-of select="team[2]"&gt; <br />
&lt;/h2&gt; <br />
&lt;p&gt;Played on &lt;xsl:value-of select="date"&gt;&lt;/p&gt; <br />
&lt;p&gt;Result: <br />
&lt;xsl:value-of select="team[1] "&gt; <br />
&lt;xsl:value-of select="team[1]/@score"&gt;, <br />
&lt;xsl:value-of select="team[2] "&gt; <br />
&lt;xsl:value-of select="team[2]/@score"&gt; <br />
&lt;/p&gt; <br />
&lt;/xsl:template&gt; <br />
<br />
&lt;/xsl:transform&gt; <br />
<br />
<br />
<br />
<br />
<br />
<span style="font-family: 宋体">这个样式表包括两个模板规则，一个匹配</span> &lt;results&gt; <span style="font-family: 宋体">元素，另一个匹配</span> &lt;match&gt; <span style="font-family: 宋体">元素。</span>&lt;results&gt; <span style="font-family: 宋体">元素的模板规则输出页面的标题，然后调用</span> &lt;xsl:apply-templates&gt;<span style="font-family: 宋体">，这是一个</span> XSLT <span style="font-family: 宋体">指令，它将处理当前元素的所有子代，对于每个子代都使用其适当的模板规则。在本例中，</span>&lt;results&gt; <span style="font-family: 宋体">元素的所有子代都是</span> &lt;match&gt; <span style="font-family: 宋体">元素，所以会用第二个模板规则来处理它们。规则输出了一个标识比赛的次级</span> HTML <span style="font-family: 宋体">标题（以</span> "Brazil versus Scotland" <span style="font-family: 宋体">的形式），然后生成</span> HTML <span style="font-family: 宋体">段落，给出了比赛的日期和两队的比分。</span> <br />
<br />
<span style="font-family: 宋体">该转换的结果就是一个</span> HTML <span style="font-family: 宋体">文档。</span> <br />
<br />
<span style="font-family: 宋体">这是一种非常简单的表示信息的方法。然而，</span>XSLT <span style="font-family: 宋体">的功能比这要强大得多。清单</span> 3 <span style="font-family: 宋体">包含了另一个可以操作相同源数据的样式表。这次，样式表计算一个比赛名次表，用来显示锦标赛结束时各队的名次。</span> <br />
<br />
<span style="font-family: 宋体">清单</span>3. <span style="font-family: 宋体">计算球队名次表的样式表</span> <br />
&lt;xsl:transform <br />
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" <br />
version="1.0"&gt; <br />
<br />
<br />
&lt;xsl:variable name="teams" select="//team[not(.=preceding::team)]"&gt; <br />
&lt;xsl:variable name="matches" select="//match"&gt; <br />
<br />
&lt;xsl:template match="results"&gt; <br />
<br />
&lt;html&gt;&lt;body&gt; <br />
&lt;h1&gt;Results of Group &lt;xsl:value-of select="@group"&gt;&lt;/h1&gt; <br />
<br />
&lt;table cellpadding="5"&gt; <br />
&lt;tr&gt; <br />
&lt;td&gt;Team&lt;/td&gt; <br />
&lt;td&gt;Played&lt;/td&gt; <br />
&lt;td&gt;Won&lt;/td&gt; <br />
&lt;td&gt;Drawn&lt;/td&gt; <br />
&lt;td&gt;Lost&lt;/td&gt; <br />
&lt;td&gt;For&lt;/td&gt; <br />
&lt;td&gt;Against&lt;/td&gt; <br />
&lt;/tr&gt; <br />
&lt;xsl:for-each select="$teams"&gt; <br />
&lt;xsl:variable name="this" select="."&gt; <br />
&lt;xsl:variable name="played" select="count($matches[team=$this])"&gt; <br />
<br />
&lt;xsl:variable name="won" <br />
select="count($matches[team[.=$this]/@score &gt; team[.!=$this]/@score])"&gt; <br />
&lt;xsl:variable name="lost" <br />
select="count($matches[team[.=$this]/@score &lt; team[.!=$this]/@score])"&gt; <br />
&lt;xsl:variable name="drawn" <br />
select="count($matches[team[.=$this]/@score = team[.!=$this]/@score])"&gt; <br />
&lt;xsl:variable name="for" <br />
select="sum($matches/team[.=current()]/@score)"&gt; <br />
&lt;xsl:variable name="against" <br />
select="sum($matches[team=current()]/team/@score) - $for"&gt; <br />
<br />
&lt;tr&gt; <br />
&lt;td&gt;&lt;xsl:value-of select="."&gt;&lt;/td&gt; <br />
&lt;td&gt;&lt;xsl:value-of select="$played"&gt;&lt;/td&gt; <br />
&lt;td&gt;&lt;xsl:value-of select="$won"&gt;&lt;/td&gt; <br />
&lt;td&gt;&lt;xsl:value-of select="$drawn"&gt;&lt;/td&gt; <br />
&lt;td&gt;&lt;xsl:value-of select="$lost"&gt;&lt;/td&gt; <br />
&lt;td&gt;&lt;xsl:value-of select="$for"&gt;&lt;/td&gt; <br />
&lt;td&gt;&lt;xsl:value-of select="$against"&gt;&lt;/td&gt; <br />
&lt;/tr&gt; <br />
&lt;/xsl:for-each&gt; <br />
&lt;/table&gt; <br />
&lt;/body&gt;&lt;/html&gt; <br />
&lt;/xsl:template&gt; <br />
<br />
&lt;/xsl:transform&gt; <br />
<br />
<br />
<br />
<br />
<br />
<span style="font-family: 宋体">这里没有足够的篇幅来完整地说明这个样式表，简而言之，它为球队声明了一个变量，变量值是一个节点集合，其中每个参赛球队都有一个实例。然后它计算每支球队的盛、平或负的比赛场次总数，以及球队进球或失球的总数。</span><br />
<br />
<span style="font-family: 宋体">这个示例的目的是说明</span> XSLT <span style="font-family: 宋体">不单单能够对源文档中出现的文本指定字体和布局。它是一个完整的编程语言，能够以任何方式转换源数据以供显示，或者输入另一个应用程序。</span> <br />
<br />
XSLT <span style="font-family: 宋体">的优点</span> <br />
<span style="font-family: 宋体">您为什么考虑使用</span> XSLT<span style="font-family: 宋体">？</span> <br />
<br />
XSLT <span style="font-family: 宋体">给了您传统高级声明编程语言的所有好处，特别是对于转换</span> XML <span style="font-family: 宋体">文档的任务。</span> <br />
<br />
<span style="font-family: 宋体">高级语言带来的实际好处是开发生产力。但实际上，真正的价值源自于更改的潜力。与使用低级</span> DOM <span style="font-family: 宋体">和</span> SAX <span style="font-family: 宋体">接口编码的过程性应用程序相比，用于转换</span> XML <span style="font-family: 宋体">数据结构的</span> XSLT <span style="font-family: 宋体">应用程序更能适应对</span> XML <span style="font-family: 宋体">文档细节的更改。在数据库世界中，这种特性叫做数据独立性，正是由于数据独立性导致了诸如</span> SQL <span style="font-family: 宋体">之类声明性语言的成功，并使旧的引导性数据访问语言走向衰亡。我坚信在</span> XML <span style="font-family: 宋体">世界中也会这样。</span> <br />
<br />
<span style="font-family: 宋体">当然与所有声明性语言一样，</span>XSLT <span style="font-family: 宋体">也会降低性能。但是对于大多数应用程序，今天的</span> XSLT <span style="font-family: 宋体">处理器的性能已经完全能够满足应用程序的需要，并且它会变得越来越好。</span><br />
<br />
<br />
</span></span></p><img src ="http://www.blogjava.net/bobby/aggbug/230813.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bobby/" target="_blank">bobby</a> 2008-09-24 09:48 <a href="http://www.blogjava.net/bobby/archive/2008/09/24/230813.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>