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

正如原来问题的楼主所说: preceding-sibling 是指在上下文节点在原 XML 文档中的前驱节点集合。所以在 mode b 中的代码:
< xsl:if test= "not(preceding-sibling::*[@f2=current()/@f2])" >
是判断在此之前没有出现过相同的 f2, preceding-sibling 没错,但是这里有一个前提条件:同一个 f1 ,在原文件中如果当前节点存在一个相同的 f2 ,但不是同一个 f1 ,那么当前节点的 f2 将无法输出了。
如果说 f2( 代表的是城市 ) 很难有同名的,但是 mode c 呢,
< xsl:if test= "not(preceding-sibling::*[@f3=current()/@f3])" >
f3 同名的多了吧,更何况,有没有同名的城市还很难说呢。
总之为了程序的严密性,我们必须将其改成:
< ?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::*[@f1=current()/@f1][@f2=current()/@f2])" >
      < xsl:value-of select= "concat(' ',@f2,':')" / >
      < xsl:variable name= "f2" select= "@f2" / >
      < xsl:for-each select= ".." >
         < xsl:apply-templates select= "item[@f2 = $f2]" mode= "c" >
            < xsl:sort select= "@f3" / >
         < /xsl:apply-templates >
      < /xsl:for-each >
   < /xsl:if >
< /xsl:template >
< xsl:template match= "item" mode= "c" >
   < xsl:if test= "not(preceding-sibling::*[@f1=current()/@f1][@f2=current()/@f2][@f3=current()/@f3])" >
      < xsl:if test= "position()!=1" >
         < xsl:value-of select= "','" / >
      < /xsl:if >
      < xsl:value-of select= "@f3" / >
   < /xsl:if >
< /xsl:template >
< /xsl:stylesheet >
其实,最重要的一点就是清楚程序每个步骤执行的状态,并有一个清晰的模型,到底是在原 XML 文档,还是节点集合。

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