加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

使用XSLT从XML文件中删除重复元素

发布时间:2020-12-16 23:20:24 所属栏目:百科 来源:网络整理
导读:这是一个示例,如果ID相同,我想删除重复的条目.我正在从系统’A’和系统’B’中拉出命中.我希望系统’A’具有优先权(即,如果ID是重复的,则从系统’B’中删除该元素).这是我的例子: 我得到了这个结果: HitList Hit System="A" ID="1"/ Hit System="A" ID="2"
这是一个示例,如果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>

解决方法

这是一个使用密钥的高效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文档时(故意改编自提供的文档,通过在相应的As之前放置一些B来使其更有趣):

<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"/>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读