这是一个示例,如果ID相同,我想删除重复的条目。我从系统中拉出了点击数字' A'和系统' B'我想要系统' A'具有优先权(即,如果ID是重复的,则从系统中删除元素' B')。这是我的榜样:
我得到了这个结果:
<HitList>
<Hit System="A" ID="1"/>
<Hit System="A" ID="2"/>
<Hit System="A" ID="2"/>
<Hit System="B" ID="1"/>
<Hit System="B" ID="2"/>
<Hit System="B" ID="3"/>
<Hit System="B" ID="4"/>
</HitList>
I want this result (with the duplicates removed):
<HitList>
<Hit System="A" ID="1"/>
<Hit System="A" ID="2"/>
<Hit System="B" ID="3"/>
<Hit System="B" ID="4"/>
</HitList>
当前代码:
<xsl:template match="/RetrievePersonSearchDataRequest">
<HitList>
<xsl:if test="string(RetrievePersonSearchDataRequest/SystemA/NamecheckResponse/@Status) = string(Succeeded)">
<xsl:for-each select="SystemA/NamecheckResponse/BATCH/ITEMLIST/ITEM/VISQST/NCHITLIST/NCHIT">
<Hit>
<xsl:attribute name="System"><xsl:text>A</xsl:text></xsl:attribute>
<xsl:attribute name="PersonID"><xsl:value-of select="number(
REFUSAL/@UID)"/></xsl:attribute>
</Hit>
</xsl:for-each>
</xsl:if>
<xsl:if test="string(RetrievePersonSearchDataRequest/SystemB/NamecheckResponse/@Status) = string(Succeeded)">
<xsl:for-each select="SystemB/NamecheckResponse/PersonIDSearchResponse/personID">
<Hit>
<xsl:attribute name="System"><xsl:text>B</xsl:text></xsl:attribute>
<xsl:attribute name="PersonID"><xsl:value-of select="number(.)"/></xsl:attribute>
</Hit>
</xsl:for-each>
</xsl:if>
</HitList>
</xsl:template>
答案 0 :(得分:3)
这可以通过身份模板的单一覆盖来完成......
XML输入
<HitList>
<Hit System="A" ID="1"/>
<Hit System="A" ID="2"/>
<Hit System="A" ID="2"/>
<Hit System="B" ID="1"/>
<Hit System="B" ID="2"/>
<Hit System="B" ID="3"/>
<Hit System="B" ID="4"/>
</HitList>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Hit[(@System='B' and @ID=../Hit[@System='A']/@ID) or
@ID = preceding-sibling::Hit[@System='A']/@ID]"/>
</xsl:stylesheet>
<强>输出强>
<HitList>
<Hit System="A" ID="1"/>
<Hit System="A" ID="2"/>
<Hit System="B" ID="3"/>
<Hit System="B" ID="4"/>
</HitList>
答案 1 :(得分:3)
XSLT 2.0解决方案:
<xsl:template match="HitList">
<HitList>
<xsl:for-each-group select="*" group-by="@ID">
<xsl:copy-of select="current-group()[1]"/>
</xsl:for-each-group>
</HitList>
</xsl:template>
这假设As总是先于Bs。如果不是这种情况,您可以用
替换内部指令<xsl:copy-of select="(current-group()[@System='A'], current-group[@System='B'])[1]"/>
答案 2 :(得分:3)
以下是使用密钥的高效XSLT 1.0解决方案:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kHitById" match="Hit" use="@ID"/>
<xsl:key name="kHitAById" match="Hit[@System = 'A']" use="@ID"/>
<xsl:template match=
"Hit[generate-id() = generate-id(key('kHitById',@ID)[1])]">
<xsl:copy-of select=
"key('kHitAById', @ID)[1]|current()[not(key('kHitAById', @ID))]"/>
</xsl:template>
</xsl:stylesheet>
将此转换应用于以下XML文档(故意改编自提供的文档),通过在相应的B
之前放置一些A
来使其更有趣词):
<HitList>
<Hit System="B" ID="1"/>
<Hit System="A" ID="1"/>
<Hit System="B" ID="2"/>
<Hit System="A" ID="2"/>
<Hit System="A" ID="2"/>
<Hit System="B" ID="3"/>
<Hit System="B" ID="4"/>
</HitList>
产生了想要的正确结果:
<Hit System="A" ID="1"/>
<Hit System="A" ID="2"/>
<Hit System="B" ID="3"/>
<Hit System="B" ID="4"/>