看了些关于XSLT2.0的东西,先来总结一下分组吧。
<xsl:for-each-group>是XSLT2.0新提出的分组语法。
XML源文档:
<
?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= "aaa" / >
< 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= "aaa" / >
< item f1= "江苏" f2= "南京" f3= "fff" / >
< item f1= "山东" f2= "青岛" f3= "ggg" / >
< item f1= "江苏" f2= "南京" f3= "hhh" / >
< item f1= "山东" f2= "济南" f3= "iii" / >
< /root >
XSLT文件:
<
?xml version='1.0'?
>
< xsl:stylesheet version= "2.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform" >
< xsl:template match= "/" >
< xsl:for-each-group select= "root/item" group-by= "@f1" >
< xsl:value-of select= "@f1" / >
< /xsl:for-each-group >
< /xsl:template >
< /xsl:stylesheet >
< xsl:stylesheet version= "2.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform" >
< xsl:template match= "/" >
< xsl:for-each-group select= "root/item" group-by= "@f1" >
< xsl:value-of select= "@f1" / >
< /xsl:for-each-group >
< /xsl:template >
< /xsl:stylesheet >
输出结果:
浙江江苏山东
select属性指定分组对象,例如,item;分组标准为具有相同f1属性值的item为一组。
xsl:for-each-group说明了,循环的因子为group.
<xsl:value-of select="current-group()/@f2"/>输出每一个group的每个节点的f2属性。
指令换作:
<xsl:for-each-group select="root/item" group-adjacent="@f1">
输出结果:
浙江江苏浙江山东江苏山东江苏山东
adjacent意为相邻的,临近的。它也是把具有相同的值的节点划为一组,但更严格的条件是,节点必须相邻(连续)。
若指令换作:
<xsl:for-each-group select="root/item" group-starting-with="item[position() mod 2 =0]">
则输出结果:
浙江江苏山东江苏江苏
可以看出输出了第1,2,4,6,8个item节点的f1属性。也就是说分成了5组,item[1],
item[2,3],item[4,5],item[6,7],item[8,9]
group-starting-with指定一个模式,符合该模式的节点被作为新的分组的开始,比如,第2,4,6,8个item。而select所指定的第一个节点,无论其是否符合该模式,都作为第一个分组的开开始,比如第一个item。注意,group-starting-with所指定的模式,跟select所指定的节点集合没有任何关系,比如父子关系。可参照
<xsl:for-each-group select="root/item" group-adjacent="@f1">
group-adjacent所指定的值@f1是root/item的属性。
理解了group-starting-with,那么group-ending-with也就容易理解了。
最后再来看那个“
用xsl实现排序和判别重复记录 ”中所提到的问题,在XSLT2.0就容易解决了。
<
?xml version='1.0'?
>
< xsl:stylesheet version= "2.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform" >
< xsl:template match= "/" >
< xsl:for-each-group select= "root/item" group-by= "@f1" >
< xsl:sort select= "@f1" / >
< xsl:text >
< /xsl:text >
< xsl:value-of select= "concat(@f1,'-')" / >
< xsl:for-each-group select= "current-group()" group-by= "@f2" >
< xsl:sort select= "@f2" / >
< xsl:value-of select= "concat(' ',@f2,':')" / >
< xsl:for-each-group select= "current-group()" group-by= "@f3" >
< xsl:sort select= "@f3" / >
< xsl:value-of select= "@f3" / >
< xsl:if test= "position() != last()" >, < /xsl:if >
< /xsl:for-each-group >
< /xsl:for-each-group >
< /xsl:for-each-group >
< /xsl:template >
< /xsl:stylesheet >
< xsl:stylesheet version= "2.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform" >
< xsl:template match= "/" >
< xsl:for-each-group select= "root/item" group-by= "@f1" >
< xsl:sort select= "@f1" / >
< xsl:text >
< /xsl:text >
< xsl:value-of select= "concat(@f1,'-')" / >
< xsl:for-each-group select= "current-group()" group-by= "@f2" >
< xsl:sort select= "@f2" / >
< xsl:value-of select= "concat(' ',@f2,':')" / >
< xsl:for-each-group select= "current-group()" group-by= "@f3" >
< xsl:sort select= "@f3" / >
< xsl:value-of select= "@f3" / >
< xsl:if test= "position() != last()" >, < /xsl:if >
< /xsl:for-each-group >
< /xsl:for-each-group >
< /xsl:for-each-group >
< /xsl:template >
< /xsl:stylesheet >
呵呵,最后一个小地方,<xsl:for-each-group>下的position()是指当前分组在总组数的位置。
转载于:https://blog.51cto.com/electiger/18645