Xml 如何根据条件删除重复节点

Xml 如何根据条件删除重复节点,xml,xslt,duplicate-removal,Xml,Xslt,Duplicate Removal,请帮助我从xml中删除重复节点。删除重复节点的条件相当复杂 条件1:在policyKey节点下的每个策略节点中,我必须检查policyNbr和PolicyFormCode/code以及policyEffectiveDt和policyID 在所有策略节点中都相同如果它们相同,我只保留其中包含sourceSystemCd/code='SCBP'的策略节点 条件2:如果在上述条件policyNbr和PolicyFormCode/code以及policyEffectiveDt和policyID中的任何一

请帮助我从xml中删除重复节点。删除重复节点的条件相当复杂

条件1:在policyKey节点下的每个策略节点中,我必须检查policyNbr和PolicyFormCode/code以及policyEffectiveDt和policyID 在所有策略节点中都相同如果它们相同,我只保留其中包含sourceSystemCd/code='SCBP'的策略节点

条件2:如果在上述条件policyNbr和PolicyFormCode/code以及policyEffectiveDt和policyID中的任何一个具有不同的值,我需要显示所有th policy节点

条件3:在策略1和策略2中,policyNbr和policyFormCd应该相同,那么我们必须使用其中的policyId解除策略。如果不相等,则显示两者。这可能吗?所有条件都应该在单个xsl中工作

条件1: 输入xml:

    <policies>
    <!-- policy 1-->
    <policy>
        <policyKey>
            <policyNbr>4567</policyNbr>
            <policyEffectiveDt>2014-11-14</policyEffectiveDt>
            <policyFormCd>
                <code>669</code>
            </policyFormCd>
        </policyKey>
        <transactionSplitTrans>
            <sourceSystemCd>
                <code>ARA</code>
            </sourceSystemCd>
        </transactionSplitTrans>
    </policy> 
    <!-- policy 2-->
      <policy>
        <policyKey>
            <policyNbr>4567</policyNbr>
            <policyEffectiveDt>2014-11-14</policyEffectiveDt>
            <policyID>54545</policyID>
            <policyFormCd>
                <code>669</code>
            </policyFormCd>
        </policyKey>
        <transactionSplitTrans>
            <sourceSystemCd>
                <code>SCBP</code>
            </sourceSystemCd>
        </transactionSplitTrans>
    </policy> 
    <!-- third -->
    <policy>
        <policyKey>
            <policyNbr>1234</policyNbr>
            <policyID>115774001</policyID>
            <policyEffectiveDt>2014-11-14</policyEffectiveDt>
            <policyFormCd>
                <code>660</code>
            </policyFormCd>
        </policyKey>
        <transactionSplitTrans>
            <sourceSystemCd>
                <code>ARAR</code>
            </sourceSystemCd>
        </transactionSplitTrans>
    </policy>
    <!-- fourth  -->
    <policy>
        <policyKey>
            <policyEffectiveDt>2014-11-14</policyEffectiveDt>
            <policyFormCd>
                <code>660</code>
            </policyFormCd>
            <policyID>115774001</policyID>
            <policyNbr>1234</policyNbr>
        </policyKey>
        <transactionSplitTrans>
            <sourceSystemCd>
                <code>SCBP</code>
            </sourceSystemCd>
        </transactionSplitTrans>
    </policy>
</policies>
Condition 3的预期输出:

<policies>
 <!-- policy 2-->
    <policy>
    <policyKey>
        <policyNbr>4567</policyNbr>
        <policyEffectiveDt>2014-11-14</policyEffectiveDt>
        <policyID>54545</policyID>
        <policyFormCd>
            <code>669</code>
        </policyFormCd>
    </policyKey>
    <transactionSplitTrans>
        <sourceSystemCd>
            <code>SCBP</code>
        </sourceSystemCd>
    </transactionSplitTrans>
</policy>
</policies>
belwo xslt的条件1和条件2工作正常。需要在同一xsl中包含条件3。

您可以使用键“分组”重复项。它将是一个包含所有字段的连接键

<xsl:key 
    name="policy"
    match="policy" 
    use="concat(policyKey/policyNbr, '|',
                policyKey/policyEffectiveDt, '|',
                policyKey/policyFormCd/code, '|',
                policyKey/policyID)" />

然后,您可以使用一个模板来忽略模板,如下所示:

    <xsl:template match="policy[count(
      key('policy', concat(policyKey/policyNbr, '|', 
                           policyKey/policyEffectiveDt, '|', 
                           policyKey/policyFormCd/code, '|', 
                           policyKey/policyID))) > 1 
      and transactionSplitTrans/sourceSystemCd/code != 'SCBP']" />

试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:key 
        name="policy"
        match="policy" 
        use="concat(policyKey/policyNbr, '|',
                    policyKey/policyEffectiveDt, '|',
                    policyKey/policyFormCd/code, '|',
                    policyKey/policyID)" />

    <xsl:template match="policy[count(key('policy', concat(policyKey/policyNbr, '|', policyKey/policyEffectiveDt, '|', policyKey/policyFormCd/code, '|', policyKey/policyID))) > 1 and transactionSplitTrans/sourceSystemCd/code != 'SCBP']" />

    <xsl:template match="@*|node()" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>


在上面的示例中,第二个和策略具有不同的“policyEffectiveDt”值。这是正确的吗?谢谢嗨,提姆,我已经改正了。现在是同一个生效日期。嗨,蒂姆,非常感谢。工作正常,但我还有一个条件需要满足。你能帮我一下吗。通过将此代码命名为Hi-Tim,我为条件3添加了xsl:key,以使其正常工作。