TechWeb-技术社区 » 系统设置 » 网页设计 » 应用程序开发者应了解XSLT 2.0新特性


2008-5-14 09:57 deeek
应用程序开发者应了解XSLT 2.0新特性

除非你整个假期一直在看《萤火虫》(Firefly)全集和电影《冲出宁静号》(即Serenity,根据Firefly改编),并比较家庭成员向洗劫一个小镇的Reavers怪物打开他们的礼物,否则你可能已经听说现在万维网联盟在推荐XSLT 2.0。
MD8E0D/Vz;\m 0k4b0_v'U(U _
你想到的问题是——现在推荐XSLT 2.0是什么意思?简单来说,这表示XSLT 2.0就像刻在了石头上,那些编写XSLT的程序员现在可以使用它,写他们的XSLT处理器,而不必担心被最后一刻的改变弄得不知所措。x1_2[n uV^
+cJr?*A-I'g
不过,对我来说,XSLT 2.0得到正式采用和度假这两件事激发我建立一个XSLT 2.0最佳功能的简短列表。你可以把它看作是一个“最佳”特性集,我认为它们是最常用的一些特性。XSLT 1.0中有一些特性,我发现我一年之中也只用了一两次。除开那些现在无益的特性,我主要讨论那些能够立即满足应用程序开发需求的特性。
F8[uy Ak~EB@ A9yo8l!hC
分组
@2W;FF9_2[
*^3hu#|x oK7r(Q 我发现,似乎每次我开始写一个XSL式样表,随后就需要用到分组信息。这种需求可能是由于某种对数据进行分类,使其更具可读性的深层次要求所引起的;或者只是由于我神经过敏!可能制定这些要求的人以前在国家狩猎委员会工作:“你可以钓一只鲑鱼和六磅其它供垂钓的鱼或一磅供垂钓的鱼和一只鲑鱼。”如果你曾经看过有关钓鱼方面的法律,你就会明白我的意思。 jP"S!X5r

8G [kG~A4xti%|H 在XSLT 1.0中,使用分组就像在冒险,这些事情需要不断实践,像是在洞穴探险时不被Grue怪吃掉。XSLT 1.0中的首选分组方法叫做Meunchian分组,它由Oracle的Steve Meunch开发。
p1a b(c)W6F+i v
e&ll ])q'gg 它的工作方式如下:编码一个xsl:key元素,指定将会用作关键字的元素或属性,以及关键字提交的元素。比较每个关键字的第一个实例提交的元素的ID和文档中的相同元素ID即可完成分组。如果两个ID匹配,则节点相同。这保证式样表中每个关键字只处理一次,并可以处理含有那个关键字值的所有元素。4}4g:g$V0I(MCv7J!c }?`

c:|p#\~c;Km#K [ 下面列出一个XML样本文档和一个XSLT 1.0 Muenchian分组实例,如列表A和B。2yS9~ B&V!l1hBU
B ]$W v#c
列表A——XML样本文档"M)]h)feK

0HA9JIn7f6iZ7H <?xml version="1.0" encoding="UTF-8"?>Myl6g)w2i HF3J
)i:yx-mXE]
<world>4q!E1S:eS-P)y
C4O0q0\(WX'b9c `0A
<country name="Canada" continent="North America">#F:hT~:Q
-{5@T$X sV2H{3eU:d
<city>Toronto</city>x ndon;DM

2Sv z@ o(g$`!? <city>Vancouver</city>1p;Nl/u:r9C#z vb!m

.C6@h hoJ;GU"VxF </country>
n Q|&C7Jt4|X]M Q&x O G/\p
<country name="Jamaica" continent="North America">j3Ab5w#?k T;J

1I.]9pa py.}%J/? <city>Kingston</city>.[4yz'HP6`
[^ ~;n)I ~z
<city>Ocho Rios</city>
]WR,zx? 0Zm`btb
</country>
1|g$z |:H/uZ
7]7o0rG V r*o)_ <country name="United States" continent="North America">'B@3W$w#m9Q Ar
z#BdO[6jp
<city>Allentown</city>ib H@ z#ZI4H

_7pbRc9QN <city>Mobile</city>
P&Q-rhv9Xf7Z$l7Sa J7N$[,Q3S.P
</country>
'onoS;D$[
Ju~e7@xU <country name="United Kingdom" continent="Europe">d6m-O:d+Tb#B+Nn

'E*T'Xk9n-Y3f <city>London</city>8k^p9oi.f3w~7_L1u

wu Mv-m1_:~7^g <city>Dundee</city>
+l E(]p},W .du UXD5i
</country>
.N&R Zn.{Za/Z %I/g y] o6L5YL
<country name="France" continent="Europe">
{*E)^5DW1|3~{![D
lk(|*u)c?*eg? <city>Paris</city>
5E"zX@EY`A X~ BjfV9`C%m'p
<city>Nice</city> U9rq7{2z x!k:B `
\.g)o*x iA p
</country>6v A;]rnl9BP a
tTEip
<country name="Japan" continent="Asia">:YQ+[v9V)i
w-S/VE"dB6f
<city>Tokyo</city>
C6p8^1AR} J X-c|Ca;_6F[
<city>Osaka</city>
]6H |-o#t x+o)T#n@;]-V:H4Z
</country>
/H5d1ln9TR[ 5q+dN$MU4[:Dl&i'o+W
</world>5lW'{(dE
6X$vq;]:Eg
列表B——XSLT 1.0 Muenchian分组&LyK!d%Wt
7c#t3|{ ]G*Q
<?xml version="1.0" encoding="UTF-8"?>
XyTdK8}.i u
S\3t X.p <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
ZZ$~!Rj5aG
"pm;n'o+C <xsl:key name="keyContinent" match="//country" use="@continent"/>1x1G#z s'P4uV
W ?8@7E9iZ;\g1KV
<xsl:template match="/"> uu*K+ZqMPur%{@
G-O1q$A J6Fl{ qZ
<xsl:element name="world">
mc)is eU&V
&]fz3^KW <xsl:for-each select="//country[generate-id(.) = generate-id(key('keyContinent',@continent)[1])]">
9wDz!k3a5K
WR%`4`x`|d \ <xsl:sort select="@continent" data-type="text" order="ascending"/>r1ncS!p#G^

/H@ T!Uc{+H!\E <xsl:variable name="continent" select="@continent"/>
K%tV-l z$I-d !?Jy&S ~8r"b n4d
<xsl:apply-templates select="//country[@continent = $continent]" mode="group">
#Q-hUmyZ P Bot"Y+i:lq\}G;M
<xsl:sort select="@name" data-type="text" order="ascending"/>
)f;ZyS#S] 3xR$tSa:Kx
</xsl:apply-templates>
*]-hz;^6Q"W-T(T }4@+D5^uA n9B1fI
</xsl:for-each>
M4U%}H$xvtOteTp 9S%Q8l.a6IX8Bo;A"w
</xsl:element>9xqeh^O3bn`
H/X#mh+bE O9P
</xsl:template>
fc"^0lc$l
z H"W/F;P#t9m {([o <xsl:template match="*" mode="group">k(fn.P'[$^L
6`Y;BgC
<xsl:copy-of select="."/>5N5Wa+xU

I&p,r'nG ohb#m </xsl:template>9m7EHOVw0q ?
$U pk I2[$W
</xsl:stylesheet>
\/j3SZ P1Z%q g4]
{|K&?7@&H p 在XSLT 2.0中,分组方法有了一些改变,但应该指出的是,Meunchian分组方法依然可用。所不同的是,Meunchian分组为可选方法,因为XSLT 2.0中内置了分组功能,因此实际上不必再使用Meunchian分组。开发者可以使用xsl:for-each-group来代替它,如列表C所示。
a0A;bI5l@;x3ji
#rA6?9h0YHG)}s 列表C——XSLT 2.0中的分组
z9\9uIF /~4I F ZZz2a3b
<?xml version="1.0" encoding="UTF-8"?>
4`Yr*^q%V
q(^2Gn7V@A <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xdt="http://www.w3.org/2005/xpath-datatypes">Z0@;K B.A9F;j+F,C8H6Y)|
z(]K{dE S,x
<xsl:template match="/">
eaA*c.K LATy)_5_ o:O{mqD
<xsl:element name="world">:hJ4L F9TUsR
lb I&p[8Cym4t
<xsl:for-each-group select="//country" group-by="@continent">;^+k]4XY9@;[@M
mP#nn t0od u,c
<xsl:sort select="@continent" data-type="text" order="ascending"/>%O7a ~!oO0__]

B9yz3w6vju'P <xsl:variable name="continent" select="@continent"/>
Mr3?CO`I s)o5nV8B#e? }
<xsl:apply-templates select="//country[@continent = $continent]" mode="group">N*I(\6r]`

/A/F;s$Ey4fMe]mj <xsl:sort select="@name" data-type="text" order="ascending"/>M!~Hc}
b1o4W/{#dN:I5aq
</xsl:apply-templates>
zR^%vcFf V N)Xq 5W)cZ(l e MG
</xsl:for-each-group>;AS M ni~&C5b
}8Q V;u,C
</xsl:element>
)s'T { E#X;f6t.E "}N1i9|_jvu c
</xsl:template>'Q6ABd8`q,qY

F v~-pYJK <xsl:template match="*" mode="group">T{v`/@#S)gR-NE

,}^&Y x.M <xsl:copy-of select="."/>zk;so$k|yZ\B

U*v;z|;o.j] </xsl:template>
'['j#v(m$bv#h+A %X)R^*l*sW k,b1k_
</xsl:stylesheet>
8^vM"jp:` EM!j1\ o F1[!Z
虽然这些分组方法各不相同,但它们的最终结果是一样的,如列表D所示。

2008-5-14 09:57 deeek
列表D——分组结果
6u1]LJ7rT s:[OQ4M @
<?xml version="1.0" encoding="UTF-8"?>
X7u(u!I?:W AZ?
'J9lNi3V}zh <world>RI9r8m^

k tWp.M <country name="Japan" continent="Asia">P5J l{X
e]!u1M:cG/V
<city>Tokyo</city>
o-V|7{ V8D\`O
CM\\_W <city>Osaka</city>;Nr/U ] YC;V
"J,UY.yGKrVY+V,?
</country>BnW{go
,R3YD{/B5m4X#]K7[
<country name="France" continent="Europe">\v*H!D p E
X7g@b!f,G"H]#R
<city>Paris</city>
$hC,{"]/k-p*ogf
d(|!A3{ xU <city>Nice</city>3?+TOS4b1R

ye&V G!B6g0w"X </country>+z iO-e_3Z4sI
f,CK'g4Iq a*j.ba^
<country name="United Kingdom" continent="Europe">0]9I+e3P,{+lA
r'z#ky6HK
<city>London</city>#[%o'~V'f+~#Vs2a

JQW"^H~0t:Xj <city>Dundee</city>
DF P*u}]c%|1PV
\:S(K#j%G6uIc </country>
2L0q#XX^yc.vHQv'A
A q)Hli}k <country name="Canada" continent="North America">e3k|f(k1c
8aH2\+D1Dm0T0W
<city>Toronto</city>C+j8J;n?~zM+S
&D~I v]'t+l:F
<city>Vancouver</city>&pww&MH#mZ"j n
8@'j0V*Cx
</country>
NB+G+{%ONN
Ct AGB5X OS <country name="Jamaica" continent="North America">
s c x.~HA!e8} ]:VH2DJVs l Z9^8N
<city>Kingston</city>UE}z/xM

dL#EEq ~;J <city>Ocho Rios</city>s fo;sjsW
5Du:H4Z M(d!L.^*S h
</country>4ZM*w-jX7EO\#q6v
$Jm:K9C)OE w
<country name="United States" continent="North America">
"sFu7U D zS
AYf'}-caH0_ <city>Allentown</city>"R*J%k(o7b+m

P5j Zf-U <city>Mobile</city>
r4jbLF1}!W1X0y
\5F8m0G@sA r!J2b g2j(dU </country>
u^2b4H0@
)H F3^ Y/fi%wo X&xp </world>
)Do _|-]\V
;YD:i(h)@3Uu 多文档输出
c/R X0G8m z9[ WZq
在使用XSLT 1.0时,我经常遇到式样表输出限制。我指的是文档输出问题,它一次只允许输出一个文档。这表示有必要在结果文档生成时进行处理。,`/{LsR5H`?S

7XHN#rZ1QG 以列表A中的XML文档为例,假设我们要把它分成几个XML文档,每个国家一个。过去必须用选择的语言编写一些代码建立单独的XML文档。XSLT 2.0改变了这种做法。
OKNN @:Qm.zq t"[QJ.z)M9Y
现在XSLT 2.0使用xsl:result-document元素,它与xsl:output元素结合生成几个输出文档。有趣的是,使用方法属性,不同的xsl:output文档可以用来生成不同的文档类型。列表E中的式样表说明了使用这种特性的一种可能方法,列表F-L中的XML文档为处理结果。
)|1|J!t~
f,wt,V:V"e&j3Ro 列表E——在XSLT 2.0中生成多个输出文档
%{,A k:`.qz? ^ ?1mg,V&M+Q)Gym
<?xml version="1.0" encoding="UTF-8"?>
!v+zA^3@ tG(}Xvc #[U4b+q)tTU} _
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xdt="http://www.w3.org/2005/xpath-datatypes">
#[w fD kX*r j(`w QWU
<xsl:output name="xml" method="xml"/>(B,k2\3H z(q0A
L`"W!c(zp h
<xsl:template match="/"> _HIo F`:C
}@)ps3rB!} _
<xsl:apply-templates select="//country"/>
^S0u Z)bP/m,l
C w N$t? k#~?~/Z </xsl:template>1wF]QLg._U-\
F P fq|
<xsl:template match="country">
\mu&^,f%Bb +V+Ld@uD
<xsl:variable name="name" select="concat(@name,'.xml')"/>yA$I%O%V"\)N-F/ff\ U
l:p]%a x[#P ?`
<xsl:result-document href="" format="xml">f+Yr^(Xp%Wc
RNK{Q Z
<xsl:copy-of select="."/>5{;B6bC&W+wA)L
8n#r J1{F(} i(|
</xsl:result-document>
%y+r0w,NV#og!yt ;Kz"X f^~o]}4u
</xsl:template> [(W0i"JU|b'`

|7|sB ~Yp.~ </xsl:stylesheet>
]sm;i7j(u7a +N6g,SYv|2~N
列表F -- Canada.xml%S1?-S H:E

*xZ{C x9n1]Z <?xml version="1.0" encoding="UTF-8"?>
~$qTv%[$d,]*iC
$d3YEm@K <country name="Canada" continent="North America"> f3m9z+y:C7hFu

8xH;q0@"Wit <city>Toronto</city>9~:R;J:H0nP

%o:NgY_!o+O9b <city>Vancouver</city>
|(x'Yf"ZJUC#N;G
[ d&IW~ </country>
,T(CB%U&x
Qy-f.f6q}(~W 列表H -- Jamiaca.xml
9En'P7D C%M0h\
m2SQ"rt/u-j <?xml version="1.0" encoding="UTF-8"?>*JS:T,}f ^S
}m|F rl'S2o`
<country name="Jamaica" continent="North America">Xr~-y"s.i

d4nWM"K*r{I:bP <city>Kingston</city> ^4x#S)c-MJ

uvcs$@tj2d#| <city>Ocho Rios</city>r z:^5M5E

Qkk$N"^8DFF </country> 9IrA1[$C^
C+T6pf uk
列表I -- United States.xmlBZO;o u!P(kr)|7z;i

`![Bq9As <?xml version="1.0" encoding="UTF-8"?>
rc$ER3n F$?:D#G#HL H/n4r7N!e.T(d0}
<country name="United States" continent="North America">l^~c"_b\p

+K%D)X2_ KZw <city>Allentown</city>
^-cgz-ib
7h8tT"che_ <city>Mobile</city>
%CW.d?9uF$Dj%K u3_Q xo'G$X
</country>
M1J9zf'UA\ 7N6ku+\'kA \Wj
列表J -- United Kingdom.xml
u:~ n#JA8P.K YiB8LrO
<?xml version="1.0" encoding="UTF-8"?> gAc,W*ol6M
`.Aqd5XS z
<country name="United Kingdom" continent="Europe">
;Pf9iG2@ WX&C
v%I}&}:^'?9r"k <city>London</city>
f"B7Kc2z#s)tz*q !j2s7n2r/j S(O
<city>Dundee</city>7v@ v5Nh

@}8Xm!i#G$P </country> 4Y&X4ob%dCir L$Z.c
;~4[ N XUP R
列表K -- France.xml
u(R1KM P
u%u&|n^ <?xml version="1.0" encoding="UTF-8"?>e;O uG'\v`
cS4A"i8p'qF']G
<country name="France" continent="Europe">O J d ~#H^WD

,Ca;\8Sd)N:k <city>Paris</city>g4X)E9M DY
s4^+k[!qJ&EI2p
<city>Nice</city>
r"a,}ZxLB
f'^"V0aN </country>
u${\v2d.N}f
!q.~ MC$B tH_E 列表 L -- Japan.xml
QY4vg B@N4ZD U G8r!vcu N |N
<?xml version="1.0" encoding="UTF-8"?>^6p%zK I
:v8TK;Zyw(eB R
<country name="Japan" continent="Asia">
{4s&p'Sv :`2x1V!_ zQy%_+^
<city>Tokyo</city>
g]W7mN}z (TO:{"su_
<city>Osaka</city>
}'E.wd {,b|M7|
a/? I0e:Z </country>kZ `-`,e G}
tV-RjN%z,k|.q
其它特性
,N c7xJA tq)n$i^!D$TI
除已经列举的特性外,我的最喜爱特性列表中还有其它一些特性。第一个是XPath 2.0支持。作为一个XML爱好者,我期待着试用这些新特性和XPath 2.0的功能。第二个特性,XQuery 1.0,可帮助其他人更易于理解XSLT。XQuery 1.0有望帮助那些对XPath“过敏”的用户使用XSLT 2.0。#Lyo6c(x5`Y7N
w2b2J,B+U3W
应用XSLT 2.0 lyT6RikA1C(yhU

%t-J H(iK(L1Q 不幸的是,如果你对试用XSLT 2.0版本的新特性感兴趣,当前只能使用少数几个处理器。第一个为Michael Kay的Saxon处理器,如果你希望遵从万维网联盟的推荐,这个开源XSLT处理器为你提供了一个选择。另一个是Altova的XMLSpy处理器,它是我见过的速度最快的XML编辑器。它们的网站提供这个处理器的30天试用版本。唯一的问题是,30天试用到期后,你就想购买这个处理器了!

页: [1]


Powered by Discuz! Archiver 5.5.0  © 2001-2006 Comsenz Inc.