在CSDN上无意中看到了这样一篇老帖 ,关于XSLT转换的。 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
XSLT原文:
<?xml version="1.0" encoding="GB2312"?>
<?xml-stylesheet type="text/xsl" href="sort.xsl"?>
<root>
<item f1=" 浙江 " f2=" 绍兴 " f3="aaa"/>
<item f1=" 江苏 " f2=" 苏州 " f3="bbb"/>
<item f1=" 浙江 " f2=" 杭州 " f3="ccc"/>
<item f1=" 山东 " f2=" 济南 " f3="ddd"/>
<item f1=" 山东 " f2=" 青岛 " f3="eee"/>
<item f1=" 江苏 " f2=" 南京 " f3="fff"/>
<item f1=" 山东 " f2=" 青岛 " f3="ggg"/>
<item f1=" 江苏 " f2=" 南京 " f3="hhh"/>
<item f1=" 山东 " f2=" 济南 " f3="iii"/>
</root>
<?xml-stylesheet type="text/xsl" href="sort.xsl"?>
<root>
<item f1=" 浙江 " f2=" 绍兴 " f3="aaa"/>
<item f1=" 江苏 " f2=" 苏州 " f3="bbb"/>
<item f1=" 浙江 " f2=" 杭州 " f3="ccc"/>
<item f1=" 山东 " f2=" 济南 " f3="ddd"/>
<item f1=" 山东 " f2=" 青岛 " f3="eee"/>
<item f1=" 江苏 " f2=" 南京 " f3="fff"/>
<item f1=" 山东 " f2=" 青岛 " f3="ggg"/>
<item f1=" 江苏 " f2=" 南京 " f3="hhh"/>
<item f1=" 山东 " f2=" 济南 " f3="iii"/>
</root>
要转换的结果文件:
江苏
-
南京:
fff
,
hhh
苏州:
bbb
山东 - 济南: ddd , iii 青岛: eee , ggg
浙江 - 杭州: ccc 绍兴: aaa
山东 - 济南: ddd , iii 青岛: eee , ggg
浙江 - 杭州: ccc 绍兴: aaa
意思是要把在同一个省同一个市的归纳在一起,并且省市都要按字典排序。
楼主想到了一点:轴是用在原文档中的。
其实,这个问题可以解决:
首先第一步:提取f1
代码:
<
?xml version='1.0'?
>
<
xsl:stylesheet
version=
"1.0"
xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform"
>
<
xsl:template
match=
"/"
>
<
xsl:apply-templates
select=
"root/item"
>
<
xsl:sort
select=
"@f1"
/
>
<
/xsl:apply-templates
>
<
/xsl:template
>
<
xsl:template
match=
"item"
>
<
xsl:if
test=
"not(preceding-sibling::*[@f1=current()/@f1])"
>
<
xsl:value-of
select=
"concat(@f1,'-')"
/
>
<
br/
>
<
/xsl:if
>
<
/xsl:template
>
<
/xsl:stylesheet
>
OK,
可以得到下面的结果:
江苏
-
山东 -
浙江-
山东 -
浙江-
现在需要输出第二项内容:即f2,可是该如何实现呢?我们知道apply-templates,通常只应用于子孙节点的模板。第一步我们已经到了item了,下面就是属性了,应用属性的模板,该如何实现属性的唯一性输出呢?
其实打破常理来想,我们可以再次应用item的模板,但是如何应用呢?我们应该先利用for-each将当前节点移到item的顶层,那么就可以再次应用item的模板了,但是,另一个问题又出来了,再次应用这个模板,是不是会混乱了,我们这次的目的是输出f2啊,OK,还记得吗?<xsl:templates>有一个mode属性。代码也就顺理成章的出来了(当然还得保证所选定的item节点没变):
<
?xml version='1.0'?
>
<
xsl:stylesheet
version=
"1.0"
xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform"
>
<
xsl:template
match=
"/"
>
<
xsl:apply-templates
select=
"root/item"
mode=
"a"
>
<
xsl:sort
select=
"@f1"
/
>
<
/xsl:apply-templates
>
<
/xsl:template
>
<
xsl:template
match=
"item"
mode=
"a"
>
<
xsl:if
test=
"not(preceding-sibling::*[@f1=current()/@f1])"
>
<
xsl:value-of
select=
"concat(@f1,'-')"
/
>
<
xsl:variable
name=
"f1"
select=
"@f1"
/
>
<
xsl:for-each
select=
".."
>
<
xsl:apply-templates
select=
"item[@f1 = $f1]"
mode=
"b"
>
<
xsl:sort
select=
"@f2"
/
>
<
/xsl:apply-templates
>
<
/xsl:for-each
>
<
br/
>
<
/xsl:if
>
<
/xsl:template
>
<
xsl:template
match=
"item"
mode=
"b"
>
<
xsl:if
test=
"not(preceding-sibling::*[@f2=current()/@f2])"
>
<
xsl:value-of
select=
"concat(' ',@f2,':')"
/
>
<
/xsl:if
>
<
/xsl:template
>
<
/xsl:stylesheet
>
转载于:https://blog.51cto.com/electiger/16722