??xml version="1.0" encoding="utf-8" standalone="yes"?> 在框架中?x)经帔R到处理集?nbsp;Collections (Maps, Lists, and Sets), 下面列出几个使用select 标签处理集合的列? OGNL documentation 也包括许多列? Syntax for list: {e1,e2,e3}. q个语法创徏?jin)一个包含字W串“name1”Q?#8220;name2”?#8220;name3”的ListQƈ且选择“name2”作ؓ(f)默认倹{?br />
判断一个元素是否存在于一个集合中Q用in ?not in 操作?br />
<s:if test="'foo' in {'foo','bar'}"> 例如Q获得h的亲属集合中为男性的一个子?/p>
OGNL supports basic lamba expression syntax enabling you to write simple functions. (Dedicated to all you math majors who didn't think you would ever see this one again.) Fibonacci: if n==0 return 0; elseif n==1 return 1; else return fib(n-2)+fib(n-1); The lambda expression is everything inside the square brackets. The #this variable holds the argument to the expression, which in the following example is the number 11 (the code after the square-bracketed lamba expression, #fib(11)).
下面是BaseDAOc:(x)
]]>
@Result(location = "simpleecho.jsp", name = "success"), @Result(location = "simpleecho.jsp", name = "input")
})
})
是什么意思?其是第二个@Result
写成配置文g形式该怎么写呢Q?
]]>
Struts2框架使用标准命名上下文来使用OGNL表达式,OGNL表达式处理的层对象是MapQ通常被称Z下文Map或上下文Q。OGNL认ؓ(f)在应用上下文中有一个根对象Q或默认对象Q。即不需要用Q何特D的标记p够获得根对象中的属性,如果要获得其他的对象Q则需要用标??br />
Struts2框架把OGNL context作ؓ(f)我们的ActionContextQƈ且把值栈QValueStackQ作为OGNL的根对象QValueStack是多个对象的集合Q但是对OGNL来说Q它是一个单一的对象)(j)。框架把其他对象和ValueStack一h到ActionContext中,包括展现application、session和request 上下文的MapsQ这些对象同ValueStack一P共同存在于ActionContext中?br />
|
|--application
|
|--session
context map---|
|--value stack(root)
|
|--request
|
|--parameters
|
|--attr (searches page, request, session, then application scopes)
|
Action实例L被放入ValueStack中,因ؓ(f)Action在vs中,q且vs是OGNL的根对象Q所以在讉KAction的属性时可以忽略“ # ”标记。但是,在访问ActionContext中的其他对象时必要使用“#”Q这样OGNL才能知道我们惌讉K的是Actioncontext中的其他对象Q而不L对象中查找?br />
讉KAction中的一个属?/td>
<s:property value="postalCode"/>
Actioncontext中的其他非根对象属性,可以?#8220;#”标记来获得?br />
<s:property value="#session.mySessionPropKey"/> or
<s:property value="#session['mySessionPropKey']"/> or
<s:property value="#request['myRequestPropKey']"/>
同样Action可以通过一个静(rn)态的Ҏ(gu)来获取ActionContextQ?br />
Actioncontext.getContext();
ActionContext.getContext().getSession().put("mySessionPropKey", mySessionObject);
Collections (Maps, Lists, Sets)
<s:select label="label" name="name" list="{'name1','name2','name3'}" value="%{'name2'}" />
Syntax for map: #{key1:value1,key2:value2}. q个语法创徏?jin)一个Map键值对集合Q?#8220;foo”对应“foovalue”Q?#8220;bar”对应“barvalue”Q?br />
<s:select label="label" name="name" list="#{'foo':'foovalue', 'bar':'barvalue'}" />
muhahaha
</s:if>
<s:else>
boo
</s:else>
<s:if test="'foo' not in {'foo','bar'}">
muhahaha
</s:if>
<s:else>
boo
</s:else>
选择集合的一个子集(也叫投媄(jing)Q,可以使用通配W:(x)
person.relatives.{? #this.gender == 'male'}
Lambda Expressions
fib(0) = 0
fib(1) = 1
fib(11) = 89
How the expression works
<s:property value="#fib =:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2)+#fib(#this-1)], #fib(11)" />
]]>
2 * @(#)IBaseDAO.java 2009-9-14 下午03:05:59
3 * Copyright 2009 Bobby_Guo, Inc. All rights reserved
4 */
5 package cn.commonframework.util;
6
7 import java.io.Serializable;
8 import java.util.List;
9
10 import org.hibernate.criterion.Criterion;
11
12 /**
13 * @description:公用DAO接口Q包含基本的增、删、改、查操作.
14 * @author :Bobby_Guo <br>
15 * @version :1.0 <br>
16 * @date :2009-9-14 下午03:12:53 <br>
17 * @param <T>
18 */
19 public interface IBaseDAO<T> {
20 /**
21 * 保存一个实体对?br />
22 * @param t
23 */
24 public void save(T t);
25 /**
26 * 更新一个实体对?br />
27 * @param t
28 */
29 public void update(T t);
30 /**
31 * 扚w更新
32 * @param hql
33 * @param o
34 * @return
35 */
36 public int batchUpdate(String hql,Object o);
37 /**
38 * 删除一个实体对?br />
39 * @param t
40 */
41 public void delete(T t);
42 /**
43 * Ҏ(gu)主键查找实体对象
44 * @param id
45 * @return
46 */
47 public T findById(Serializable id);
48 /**
49 * 查找所有实体对?br />
50 * @return
51 */
52 public List<T> getAll();
53 /**
54 * HQL查询
55 * @param hql
56 * @return
57 */
58 public List<T> getAllByHql(String hql);
59 /**
60 * QBC查询
61 * @param criterion
62 * @return
63 */
64 public List<T> getAllByCriteria(Criterion criterion);
65 /**
66 * QBE查询
67 * @return
68 */
69 public List<T> getAllByExample(T t,boolean enableLike,String properties);
70 /**
71 * 默认的QBE查询
72 * @param t
73 * @return
74 */
75 public List<T> getAllByExample(T t);
76 }
77 BaseDAO.java
首先注意到的是,XSL文g本nx一?XML文gQ所以在XSL文g的开_(d)一h和XML文g相同的声明。W3Cq个XML的标准机构ؓ(f)XSL定义?jin)很多标讎ͼ元素Q,XSL文g是q些标记和HTML标记的组合。在XSL文g中,必须有如下一行的代码Q?
Qxsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"Q?
q里Qxsl:stylesheet是XSL文g的根元素Q在根元素中包含?jin)所有的排版样式Q样式表是p些排版样式组合成的;xmlns:xsl="http://www.w3.org/TR/WD-xsl"q一句主要用来说明该XSL样式表是使用W3C所制定的XSLQ设定值就是XSL规范所在的URL地址?
实际上,q里"http://www.w3.org/TR/WD-xsl"是一个名字空_(d)namespaceQ,我们在上面关于XML Schema语法介绍的时候已l进行过介绍。这是一个标准的名字I间?stylesheet"Q?template"Q?for-each"{等关键字都是这个名字空间所定义的?
当然在xsl:stylesheetq可以设定其他的属性,其他的属性有Q?
1Q?default-spaceQ决定是否保留XML文g中的I白Q仅当gؓ(f)"default"时保留?
2Q?indent-resultQ决定是否保留XSL文g中的I白Qgؓ(f)"yes"时保留?
3Q?languageQ设定在XSL文g中用的脚本语言?
然后Q我们在上面的代码中看到有如下的代码Q?
Qxsl:template match="/"Q?
………
Q?xsl:templateQ?
q里实际上是表示?jin)XSL解析器对XML文档的处理过E,它从根节点(由match="/"军_Q这?/"pC根节点Q开始,对XML文档q行遍历QƈҎ(gu)具体的代码从XML文档中取出相关的内容。这里关于属性match的取值是一个比较复杂的问题。它实际上表C的含义是从XML文档中取Z个特定的节点集合QXML文档可以被看成一个树(wi)的结构,q个在后面关于XML解析器分析中有详l的介绍Q。这里,我们通过几个单的例子来说明属性match的取倹{?
比如下面一行代码:(x)
Qxsl:template match="/"Q?
q行代码的意思是告诉XSL解析E序Q当前需要处理的节点是根节点下的内容Q用"/"来表C根节点Q,其实q里的match值内容的~写是要W合XPath的语意。关于XPath我们在后面的章节中会(x)q行详细的介l?
再D一个例子:(x)
Qxsl:template match="shoppingcart/item"Q?
q行代码要匹配的是shoppingcart元素下的item元素。而不shoppingcart在XML文档l构?wi)下的哪一个位|。比如XML文档的其中一D|q样的?
QshoppingcartQ?
QitemQ?
QitemNoQ?333Q?itemNoQ?
QitemNameQ屠龙刀Q?itemNameQ?
Q?itemQ?
QitemQ?
QitemNoQ?444Q?itemNoQ?
QitemNameQ离别钩Q?itemNameQ?
Q?itemQ?
Q?shoppingcartQ?
那么它匹配的内容是
QitemQ?
QitemNoQ?333Q?itemNoQ?
QitemNameQ屠龙刀Q?itemNameQ?
Q?itemQ?
QitemQ?
QitemNoQ?444Q?itemNoQ?
QitemNameQ离别钩Q?itemNameQ?
Q?itemQ?
而下面这个例子:(x)
Qxsl:template match="/shoppingcart/item"Q?
表示只匹配XML文档根节点下的shoppingcartq个节点下的所有item元素。也是说如果shoppingcart不是直接在根节点下的Q它?yu)׃W合q个匚w条g?
再看一个例子:(x)
Qxsl:template match="price[@unit='USD']"Q?
q个例子说明要匹配的是这L(fng)节点Q一个带unit属性的元素priceQ而且unit的值必Mؓ(f)"USD"。比如一DXML代码是这L(fng)?
QpriceQ?
QunitQUSDQ?unitQ?
QamountQ?00Q?amountQ?
Q?priceQ?
QpriceQ?
QunitQRMBQ?unitQ?
QamountQ?00Q?amountQ?
Q?priceQ?
那么它匹配的内容是Q?
QpriceQ?
QunitQUSDQ?unitQ?
QamountQ?00Q?amountQ?
Q?priceQ?
实际上,存在许多各种W号用来表示匚w规则Q我们在XPath语法介绍中会(x)详细涉及(qing)到。现在知道这么一个大概的概念可以了(jin)?
我们用<xsl:template match="具体匚w表达?Q这条语句找C(jin)一些节炚w合以后,我们p从这个集合中扑ֈ特定的元素或者元素属性的|那么采用什么语句呢Q就是用xsl:value-of select = ""q样的语句来L特定的内宏V?
比如下面的例子中Qxsl:value-of select="名称"/Q这行代码就是表C定位XML文档中的名称元素的内宏V在指定集合中可能存在多个名字元素,如果我们需要把它们一一列D出来q行处理的话Q就需要用到语句xsl:for-each select = ""Q注意这里涉?qing)到一个作用范围的概念Q也是说xsl:for-each select = ""q条语句是在一个指定的集合I间中执行的。比如上面例子中如下的代?
q里的<xsl:for-each select="词语"Q是在<xsl:template match="|络用语集合"Q所指定的集合空间里面寻扑օ?词语"的?
同时Q我们需要注意的是上面的代码中,出现?jin)一条语?
Qxsl:apply-templates select="|络用语集合" /Q?
它表CZ么意思呢Q它实际上相当于C++中的一个过E调用,当XSL解析器执行到该语句的时候,它就?x)在代码中寻找以Q?xml:namespace prefix = xsl /Q<xsl:template match="|络用语集合"Q开头的代码Q所以在上面的例子程序中Q以下的代码可以看成是过E的实现?
把看成是一个过E调用,把<xsl:template match="|络用语集合"Q?
…….
Q?xsl:templateQ?
看成是过E的实现Q有助于我们对XSL解析器执行过E的理解。这里match="|络用语集合"可以理解为是传递给q程的参敎ͼ它表CE实C的集合范围是该match所匚w的节炚w合空_(d)"|络用语集合"Q?
如果我们要对表格中的元素q行排序该什么办呢?比如_(d)在上面的例子中,我们需要按照名U进行排序。很单对Q改写ؓ(f)如下的Ş式即可:(x)
Qxsl:for-each select="词语" order-by="+名称"Q,其中"+"表示按降序排列;"-"表示按升序排列?order-by"是XSL语法中的关键字?
如果我们只想在列表中取出某几行该怎么操作呢?比如我们只想取出名称?恐龙"的行Q见下面的代码:(x)
q里有一个新的句法ؓ(f)Q<xsl:template match="|络用语集合"Q?
Qtable Border="1"Q?
Qxsl:for-each select="词语" order-by="-名称"Q?
Qxsl:if test=".[名称='恐龙']"Q?
QtrQ?
QtdQ<xsl:value-of select="名称"/Q</tdQ?
QtdQ<xsl:value-of select="含义"/Q</tdQ?
Q?xsl:ifQ?
Q?xsl:for-eachQ?
Q?tableQ?
Q?xsl:templateQ?
它表C如?.[名称='恐龙']"为真QTRUEQ的话,执行该D里面的语句Q要是ؓ(f)假(F(tun)ALSEQ的话就不执行。它和C++中的if语句的概念基本是一L(fng)?
前面我们用<xsl:value-of select=""/Q取出的都是一个元素的|但是我们要取出元素某一个属性的D怎么做呢Q采用下面的形式Q?
Qxsl:value-of select="元素名称/@属性名U?/Q?
比如一DXML代码是这L(fng)Q?
Q王?|址="www.wangshuo.com"Q知名作家加著名评论家王朔先生的地方Q?王朔Q?
我们可以用<xsl:value-of select="王朔/@|址"/Q来得到?www.wangshuo.com"?
以上包括?jin)XSL的大多数基本的语法,更加详细和完整的介绍需要参看W3C相关的最新的文档Q可以在WWW.W3C.ORG/TR下找到?
Ҏ(gu)上面的分析,我们可以看到XSL实际上采用的是一U{换的思想Q它最l将XML文档转换为另一U可用于输出的文档,而CSS则没有Q何{换动作,在整个过E中没有M新码产生?另外Q在XSL?0%的样式规定在CSS中都有定义,但仍然有一些效果是CSS无法描述的,必须使用XSL不可。这些功能包括文本的|换、根据文本内容决定显C方式、文档内Ҏ(gu)序等Q都是XSL所独有的。再者,XSL遵从XML的语法,而CSS的语法自成体pR?
选择样式单还要考虑不同览器对样式单的支持E度。目前IE5与Netscape的最新版本都支持CSSQ但支持的程度都有限。至今ؓ(f)止,IE5不能完全支持CSS1Q即便是支持的部分也存在很多错误Q对于CSS2也只提供部分支持。Netscape在对CSS的支持上已经优于IE5Q它采用C代的Raptor/Gecko引擎技术,已经能够完全支持CSS1Q但对CSS2的支持计划尚不明朗。而对XSLT而言Q只有IE5支持QNetscape5q不支持?
XSLT 是什么类型的语言Q其用途是什么,Z么要q样设计它?q些问题可以有许多不同的{案Q初学者往往?x)感到困惑,因?f)q种语言与他们以前习(fn)惯用的语言之间有很大差别。本文尝试说?/span> XSLT。本文ƈ不试图教(zhn)编?/span> XSLT 样式表,它将说明q种语言的v源,它擅长什么,以及(qing)(zhn)ؓ(f)什么应该用它?/span>
什么是 XSLTQ?/span>
XSLT 语言׃l网联盟 (W3C) 定义Qƈ且该语言?/span> 1.0 版本?/span> 1999 q?11 ?/span> 16 日作?/span>“推荐?/span>”发布Q请参阅参考资料)(j)。我已经在拙?/span> XSLT Programmers' Reference 中提供了(jin)全面的规范和用户指南Q因此我不打在本文中涵盖相同内宏V确切地Ԍ本文的目的只是读者理?/span> XSLT 适合大规模事物的哪些位置?/span>
XSLT 的角?/span>
XSLT 的最初目的是信息内容与 Web 昄分离。如其最初定义那PHTML 通过按抽象概念(如段落、重点和~号列表Q定义显C来实现讑֤独立性。随着 Web 变得来商业化Q出版h希望其输?gu)量能辑ֈ与印刷品相同的质量。这逐渐D来多C用具体显C控Ӟ如页面上材料的明字体和l对位置。然而不q的是完全可以预料其副作用,卛_相同的内容传递到替代讑֤Q如数字?sh)视机?/span> WAP ?sh)话Q印刷业的行话再现效果)(j)会(x)变得日益困难?/span>
׃吸收?jin)印刷业使?/span> SGML 的经验,?/span> 1998 q初定义?jin)一U标记语a XMLQ它用于表示独立于显C的l构化内宏V与 HTML 使用一l固定概念(如段落、列表和表)(j)不同Q?/span>XML 标记中用的标记完全是用户定义的Q其用意是这些标记应该与所x的对象(如h、地炏Vh(hun)格和日期Q相兟뀂尽?/span> HTML 中的元素本质上都是印h式(虽然处于抽象U别Q,?/span> XML 的目标是元素应该描述实际对象。例如,清单 1 昄?jin)表C球锦标赛l果?/span> XML 文档?/span>
清单 1. 表示球锦标赛结果的 XML 文档
<results group="A">
<match>
<date>10-Jun-1998</date>
<team score="2">Brazil</team>
<team score="1">Scotland</team>
</match>
<match>
<date>10-Jun-1998</date>
<team score="2">Morocco</team>
<team score="2">Norway</team>
</match>
<match>
<date>16-Jun-1998</date>
<team score="1">Scotland</team>
<team score="1">Norway</team>
</match>
<match>
<date>16-Jun-1998</date>
<team score="3">Brazil</team>
<team score="0">Morocco</team>
</match>
<match>
<date>23-Jun-1998</date>
<team score="1">Brazil</team>
<team score="2">Norway</team>
</match>
<match>
<date>23-Jun-1998</date>
<team score="0">Scotland</team>
<team score="3">Morocco</team>
</match>
</results>
如果要通过 Web 览器显C些球赛的结果,不要指望pȝ?x)生合理的布局。需要其它一些机制来告诉pȝ如何在浏览器屏幕、电(sh)视机?/span>WAP ?sh)话或真正在U张上显C数据。这是使用样式表的目的。样式表是一l说明性的规则Q它定义?jin)应如何表示源文档中标记标识的信息元素?/span>
W3C 已经定义?jin)两个系列的样式表标准。第一个是?/span> HTML 中广泛用的 CSSQ联样式表Q,当然它也可以?/span> XML 中用。例如,可以使用 CSS 来表CZ时显C发,应支付的总额应该?/span> 16 ?/span> Helvetica _体字显C。但是,CSS 不能执行计算、重新整理或排序数据、组合多个源码中的数据或Ҏ(gu)用户或会(x)话的特征个性化昄的内宏V在q个球赛结果的例子中,CSS 语言Q即使是最新版?/span> CSS2Q尚未在产品中完全实玎ͼ(j)的功能还不够强大Q不能处理这Q务。由于这些原因,W3C 已着手开发更强大的样式表语言 XSLQ可扩展样式表语aQ,qU了(jin) SGML C中开发的 DSSSLQ文档样式、语义和规范语言Q中许多好的构思?/span>
?/span> XSL 的开发过E中Q这?/span> DSSSL 中已有所预示Q,发现在准?/span> XML 文档以备昄的过E中执行的Q务可以分成两个阶D:(x)转换和格式化。{换是一?/span> XML 文档Q或其内存中的表C法Q{换成另一?/span> XML 文档的过E。格式是已转换的树(wi)状结构{换成两维囑Ş表示法或可能是一l音频流的过E?/span>XSLT 是ؓ(f)控制W一阶段“转换”而开发的语言。第二阶D?/span>“格式?/span>”的开发工作还是进行中。但实际上,大多Ch现在使用 XSL ?/span> XML 文档转换?/span> HTMLQƈ使用 HTML 览器作为格式化引擎。这是可行的Q因?/span> HTML 实际上只?/span> XML 词汇表的一个示例,?/span> XSLT 可以使用M XML 词汇表作为其目标?/span>
{换成一U语a和格式化成另一U语aq两个操作分ȝ证实的确是一U好的决{,因ؓ(f)转换语言的许多应用程序经证明无法向用hC文档。随着 XML 日益q泛地用作电(sh)子商务中的数据互换语法,对于应用E序数据从一?/span> XML 词汇表{换成另一?/span> XML 词汇表的需求也在不断增加。例如,某个应用E序可能从电(sh)视收视指南中抽取?sh)视节目的细节,q将它们插入按次付费客户的月帐单中。同Pq有许多实用的数据{换,在这些{换中源词汇表和目标词汇表是相同的。它们包括数据过滤,以及(qing)商务操作Q如施行涨h(hun)。因此,随着在系l中开始越来越多地?/span> XML 语法的Ş式用数据,XSLT 逐渐成ؓ(f)׃处理q些数据的随处可见的高语言?/span>
在拙作中Q我做了(jin)q样一个比喻:(x)XSLT ?/span> XML 的关p,好?/span> SQL 与表格化数据的关pM栗关pL型的强大功能q来自用表存储数据的思想Q而是源于 SQL 中可行的Z关系q算的高U数据操作。同PXML 的层ơ化数据模型对应用程序开发者的帮助实际上也非常。正是因?/span> XSLT 作ؓ(f) XML 数据的高U操作语a提供?jin)如此强大的功能?/span>
XSLT 作ؓ(f)语言
某些方面而言Q?/span>XSLT 作ؓ(f)一U语a来说是非常古怪的。我不打在本文中讨论已做出的设计决{的基本原理Q尽可以通过它们在逻辑上追溯到语言设计者确定的?/span> XSLT 的要求?/span>
以下概述?/span> XSLT 语言的部分主要特性?/span>
XSLT 样式表是一?/span> XML 文档。通过使用 XML 的尖括号标记语法来表C文档的l构。这U语法在某种E度上是比较W拙的,而此决策可以使该语言变得更罗嗦。但是,它确实有好处。它表示可以自动使用 XML 的所有词汇设备(例如Q?/span>Unicode 字符~码和{义,使用外部实体{等Q。它表示很容易 XSLT 样式表变成{换的输入或输出,使该语言可以作用于自w。它qɞ期望的 XML 输出块嵌入样式表变得很容易。实际上Q许多简单的样式表基本上可以写作期望输出文档的模板,q且可以一些特D指令嵌入文本中Q以便插入输入中的变量数据或计算某个倹{这׃ XSLT 在这个简单的U别上非常类g许多现有的专?/span> HTML 模板语言?/span>
基本处理范例是模式匹配。在q方面,XSLT l承?jin)文本处理语aQ如 PerlQ的传统Q这U传l可以一直追溯到 1960 q代的语aQ如 SNOBOL?/span>XSLT 样式表包括一l模板规则,每条规则都用以下方式:(x)“如果在输入中遇到此条Ӟ则生成下列输出?/span>”规则的顺序是无关紧要的,当有几条规则匚w同一个输入时Q将应用冲突解决法。然而,XSLT 与串行文本处理语a的不同之处是 XSLT 对输入ƈ非逐行q行处理。实际上Q?/span>XSLT 输?/span> XML 文档视ؓ(f)?wi)状l构Q每条模板规则都适用于树(wi)中的一个节炏V模板规则本w可以决定下一步处理哪些节点,因此不必按输入文档的原始序来扫描输入?/span>
XSLT 处理器的操作
XSLT 处理器用树(wi)状结构作为其输入Qƈ生成另一个树(wi)状结构作出?/span>
常常通过?/span> XML 文档q行语法分析来生成输入树(wi)状结构,而输出树(wi)状结构通常被串行化到另一?/span> XML 文档中。但 XSLT 处理器本w操作的是树(wi)状结构,而不?/span> XML 字符。这个概忉|初给许多用户的感觉是不切实际的,l果却对理解如何执行更复杂的转换起了(jin)关键作用。首先,它表C?/span> XSLT 处理器可以理解源文档中与?wi)状l构无关的特D之处。例如,无论属性是包括在单引号中还是在双引号中Q都不可能应用不同的处理Q因Z(x)这两种形式视ؓ(f)同一个基本文档的不同表示Ҏ(gu)。更深入地看Q它表示处理输入元素或生成输出元素是一个原子操作。不可能处理元素的开始标记和l束标记分成单独的操作,因ؓ(f)一个元素会(x)自动表示成树(wi)模型的单节点?/span>
XSLT 使用叫作 XPath 的子语言来引用输入树(wi)中的节点?/span>XPath 本质上是与具有层ơ结构的 XML 数据模型相匹配的查询语言。它可以通过按Q何方向浏览树(wi)来选择节点QƈҎ(gu)节点的值和位置应用谓词。它q包括用于基本字W串处理、数字计和布尔代数的工兗例如,XPath 表达?/span> ../@title 选择当前节点的父代元素的标题属性?/span>XPath 表达式用于选择要进行处理的输入节点、在条g处理期间试条gQ以?qing)计g便插入结果树(wi)中。模板规则中q用了(jin) XPath 表达式的化Ş?/span>“模式”来定义特定模板规则适用于哪些节炏V?/span>XPath 在单独的 W3C 推荐书中定义Q它允许使用在其它上下文中再使用的查询语aQ特别是用于定义扩展链接的 XPointer?/span>
XSLT 以传l语aQ如 Lisp?/span>Haskell ?/span> SchemeQ中的功能性编E的概念为基。样式表由模板组成,q些模板基本上是单一功能 -- 每个模板输出树(wi)的一部分定义成一部分输入?wi)的功能Qƈ且不产生副作用。用无副作用的规则受到严格控制Q除?jin){义成用类?/span> Java 的语a~写的外部代码)(j)?/span>XSLT 语言允许定义变量Q但不允许现有变量更改它的?/span> -- x有赋D句。这个策略许多新用h到困惑,其目的是Z(jin)允许逐步应用样式表。其原理是如果语a没有副作用,那么对输入文档做很小的改动时Q不必从头执行整个{换就应该可以计算出对输出文档的最后更攏V目前必说q只是理Z的可能,M现有 XSLT 处理器还不能实现。(注:(x)虽然 XSLT 以功能性编E概念ؓ(f)基础Q但它还不是一个完整的功能性编E语aQ因为它~少函数当作一U数据类型进行处理的能力。)(j)
CZ样式?/span>
在这个阶D,使用CZ?x)语言变得更清楚。清?/span> 2 昄?jin)列(gu)球赛l果的简单样式表?/span>
清单 2. 球赛结果的基本样式?/span>
<xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="results">
<html>
<head><title>
Results of Group <xsl:value-of select="@group">
</title></head>
<body><h1>
Results of Group <xsl:value-of select="@group">
</h1>
<xsl:apply-templates>
</body></html>
</xsl:template>
<xsl:template match="match">
<h2>
<xsl:value-of select="team[1]"> versus <xsl:value-of select="team[2]">
</h2>
<p>Played on <xsl:value-of select="date"></p>
<p>Result:
<xsl:value-of select="team[1] ">
<xsl:value-of select="team[1]/@score">,
<xsl:value-of select="team[2] ">
<xsl:value-of select="team[2]/@score">
</p>
</xsl:template>
</xsl:transform>
q个样式表包括两个模板规则,一个匹?/span> <results> 元素Q另一个匹?/span> <match> 元素?/span><results> 元素的模板规则输出页面的标题Q然后调?/span> <xsl:apply-templates>Q这是一?/span> XSLT 指o(h)Q它?yu)处理当前元素的所有子代,对于每个子代都用其适当的模板规则。在本例中,<results> 元素的所有子代都?/span> <match> 元素Q所以会(x)用第二个模板规则来处理它们。规则输Z(jin)一个标识比赛的ơ HTML 标题Q以 "Brazil versus Scotland" 的Ş式)(j)Q然后生?/span> HTML D落Q给Z(jin)比赛的日期和两队的比分?/span>
该{换的l果是一?/span> HTML 文档?/span>
q是一U非常简单的表示信息的方法。然而,XSLT 的功能比q要强大得多。清?/span> 3 包含?jin)另一个可以操作相同源数据的样式表。这ơ,样式表计一个比赛名ơ表Q用来显C锦标赛l束时各队的名次?/span>
清单3. 计算球队名次表的样式?/span>
<xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:variable name="teams" select="http://team[not(.=preceding::team)]">
<xsl:variable name="matches" select="http://match">
<xsl:template match="results">
<html><body>
<h1>Results of Group <xsl:value-of select="@group"></h1>
<table cellpadding="5">
<tr>
<td>Team</td>
<td>Played</td>
<td>Won</td>
<td>Drawn</td>
<td>Lost</td>
<td>For</td>
<td>Against</td>
</tr>
<xsl:for-each select="$teams">
<xsl:variable name="this" select=".">
<xsl:variable name="played" select="count($matches[team=$this])">
<xsl:variable name="won"
select="count($matches[team[.=$this]/@score > team[.!=$this]/@score])">
<xsl:variable name="lost"
select="count($matches[team[.=$this]/@score < team[.!=$this]/@score])">
<xsl:variable name="drawn"
select="count($matches[team[.=$this]/@score = team[.!=$this]/@score])">
<xsl:variable name="for"
select="sum($matches/team[.=current()]/@score)">
<xsl:variable name="against"
select="sum($matches[team=current()]/team/@score) - $for">
<tr>
<td><xsl:value-of select="."></td>
<td><xsl:value-of select="$played"></td>
<td><xsl:value-of select="$won"></td>
<td><xsl:value-of select="$drawn"></td>
<td><xsl:value-of select="$lost"></td>
<td><xsl:value-of select="$for"></td>
<td><xsl:value-of select="$against"></td>
</tr>
</xsl:for-each>
</table>
</body></html>
</xsl:template>
</xsl:transform>
q里没有_的篇q来完整地说明这个样式表Q简而言之,它ؓ(f)球队声明?jin)一个变量,变量值是一个节炚w合,其中每个参赛球队都有一个实例。然后它计算每支球队的盛、^或负的比赛场ơLQ以?qing)球队进球或q的L?/span>
q个CZ的目的是说明 XSLT 不单单能够对源文档中出现的文本指定字体和布局。它是一个完整的~程语言Q能够以M方式转换源数据以供显C,或者输入另一个应用程序?/span>
XSLT 的优?/span>
(zhn)ؓ(f)什么考虑使用 XSLTQ?/span>
XSLT l了(jin)(zhn)传l高U声明编E语a的所有好处,特别是对于{?/span> XML 文档的Q务?/span>
高语言带来的实际好处是开发生产力。但实际上,真正的h(hun)值源自于更改的潜力。与使用低 DOM ?/span> SAX 接口~码的过E性应用程序相比,用于转换 XML 数据l构?/span> XSLT 应用E序更能适应?/span> XML 文档l节的更攏V在数据库世界中Q这U特性叫做数据独立性,正是׃数据独立性导致了(jin)诸如 SQL 之类声明性语a的成功,q旧的引导性数据访问语a走向C。我坚信?/span> XML 世界中也?x)这栗?/span>
当然与所有声明性语a一PXSLT 也会(x)降低性能。但是对于大多数应用E序Q今天的 XSLT 处理器的性能已经完全能够满应用E序的需要,q且它会(x)变得来好?/span>