用xsl实现排序和判别重复记录(1)

CSDN 上无意中看到了这样一篇老帖   ,关于 XSLT 转换的。
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>  
要转换的结果文件:
江苏 -   南京: fff hhh   苏州: bbb  
山东 -   济南: 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 >

你可能感兴趣的:(职场,休闲)