用xsl实现排序和判别重复记录(3)
原创
©著作权归作者所有:来自51CTO博客作者时代码农的原创作品,请联系作者获取转载授权,否则将追究法律责任
正如原来问题的楼主所说: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文档,还是节点集合。
下一篇:电脑问题解决办法

提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
删除重复记录
删除重复记录
Oracle 字段 表名 数据 -
oracle 删除重复记录
比如现在有一人员表 (表名:peosons)若想将姓名、身份证号、住址这三个字段完全相同的记录查询出来 select p1.* from persons p1,persons p2 where p1.idand p1.cardid = p2.ca
oracle table delete integer insert