XSLT对结果的分组(包括1.0和2.0新的功能)

来源:互联网 发布:田爪爱里 知乎 编辑:程序博客网 时间:2024/04/28 08:54
  XSLT2.0已经出来时间不短了,XSLT2.0相比1.0增加了五个比较激动人心的功能
今天就来看看第一个:支持分组了。在1.0中我们要对XML分组虽然可以使用很多方式,但是就算最出名的Muenchian虽然灵巧但是其复杂耗内存的方法并不受人们的推崇,在2.0中有了直接的支持,使得XML中的分组不再令人生畏,下面我们就来比较一下1.0和2.0中的分组:
数据文件:node.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml:stylesheet type="text/xsl" href="1.xsl"?>
<root>
 <node a="a1" b="b1"/>
 <node a="a2" b="b1"/>
 <node a="a2" b="b2"/>
 <node a="a3" b="b2"/>
</root>
目标结果输出:
The a: a1  a2  a3  
The b: b1  b2  

 


在1.0中没有直接的分组功能必须自己想办法来进行处理,我就拿Muenchian方法来做例子了(毕竟是最灵巧的方法,呵呵)
1.xsl(1.0版):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="
http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
 <xsl:key name="nodeA" match="node" use="@a"/>
 <xsl:key name="nodeB" match="node" use="@b"/>
 <xsl:template match="root">
  The a:
  <xsl:for-each select="./node[generate-id(.)=generate-id(key('nodeA',@a))]">
   <xsl:value-of select="@a"/>&#160;
  </xsl:for-each>
  <br/>
  The b:
  <xsl:for-each select="./node[generate-id(.)=generate-id(key('nodeB',@b))]">
   <xsl:value-of select="@b"/>&#160;
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/02/xpath-functions" xmlns:xdt="http://www.w3.org/2005/02/xpath-datatypes">
 <xsl:output method="html"/>
 <xsl:template match="root">
  The a:
  <xsl:for-each-group select="node" group-by="@a">
   <xsl:value-of select="@a"/>>&#160;
  </xsl:for-each-group>
  <br/>
  The b:
  <xsl:for-each-group select="node" group-by="@b">
   <xsl:value-of select="@b"/>>&#160;
  </xsl:for-each-group>
 </xsl:template>
</xsl:stylesheet>

  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

设定两个key值,一个名字为nodeA,一个为nodeB。他们分别都是对于node这个节点进行分组设定的,只是分组所使用的内容不同,nodeA使用的是node的a属性,nodeB使用的是b属性。
generate-id(node-set):
The generate-id function returns a string that uniquely identifies the node in the argument node-set that is first in document order. 
该函数会返回节点在整个文档中的唯一标识。
node-set key(string, object)
第一个参数是key名字,就是前面定义的<xsl:key的名字,object表示那个内容和key中的内容进行匹配,key('nodeA',@a)就是返回了第一个和当前节点的匹配内容相同的文档中的节点。
在上述的xsl中,我们添加进这样一段
<xsl:for-each select="./node">
 <xsl:value-of select="generate-id(.)"/>&#160;
 <xsl:value-of select="generate-id(key('nodeA',@a))"/>
 <br/>
</xsl:for-each>
可以看到输出值是
IDAWHIYF  IDAWHIYF
IDAZHIYF  IDAZHIYF
IDA2HIYF  IDAZHIYF
IDATGIYF  IDATGIYF
可以看到空格前的四个数据是完全不相同的,也就是每一个节点的唯一标示,使随机生成并没有固定值,但空格后的数据第二个和第三个是相同的。我们可以看一下xml数据的第二个和第三个节点:
<node a="a2" b="b1"/>
<node a="a2" b="b2"/>
他们的a属性是相同,所以说明key('nodeA',@a)在处理到第三个节点<node a="a2" b="b2"/>时返回的是符合key的第一个节点,也就是<node a="a2" b="b1"/>。
通过这种"./node[generate-id(.)=generate-id(key('nodeA',@a))]"方式就剔除重复的内容,达到了分组效果,解析结果就是:
The a: a1  a2  a3  
The b: b1  b2  

是不是很复杂啊,xslt2.0解决了这个难题,我们看一下2.0的程序:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="


只是使用了一个语句:for-each-group 通过group-by属性就将数据进行了分组,和SQL中的group-by很像对吗?它本身还有一些属性设置,往后再一一道来。

这篇文章的目的告诉大家,虽然xslt2.0的内容多了,但是对于一些操作确是简化了不少:)

原创粉丝点击