使用XSLT比较和删除XML中的重复项

时间:2016-03-16 15:08:31

标签: xml xslt

我遵循XML文档:

<root>
<Organization>
    <Organization_ID >111111</Organization_ID>
    <Organization_Code>ABC</Organization_Code>
</Organization>
<Organization>
    <Organization_ID >111111</Organization_ID>
    <Organization_Code>ABC</Organization_Code>
</Organization>
<Organization>
    <Organization_ID >111111</Organization_ID>
    <Organization_Code>ABCD</Organization_Code>
    <Organization_Type>Test</Organization_Type>
</Organization>

</root>

我需要输出为(删除重复记录):

<root>

<Organization>
    <Organization_ID>111111</Organization_ID>
    <Organization_Code>ABC</Organization_Code>
</Organization>
<Organization>
    <Organization_ID>111111</Organization_ID>
    <Organization_Code>ABCD</Organization_Code>
    <Organization_Type>Test</Organization_Type>
</Organization>

</root>

我已经在下面编写了一个可以执行此操作的代码。我的问题是我们需要比较所有子元素,看它们是否完全相同。只要我为Organization_Type设置条件,输出就会选择所有三个记录

我的代码:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

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

<xsl:template match="Organization">
    <xsl:if
        test="
            (not(following::Organization[Organization_ID = current()/Organization_ID])
            or not(following::Organization[Organization_Code = current()/Organization_Code])


            )">
        <xsl:copy>

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

我想使用但不起作用的代码:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

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

<xsl:template match="Organization">
    <xsl:if
        test="
            (not(following::Organization[Organization_ID = current()/Organization_ID])
            or not(following::Organization[Organization_Code = current()/Organization_Code])
            or not(following::Organization[Organization_Type = current()/Organization_Type])

            )">
        <xsl:copy>

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

任何帮助将不胜感激。对不起,这是我的第一篇文章,因此可能无法以正确的位置或格式正确发布。

1 个答案:

答案 0 :(得分:1)

您的样式表显示版本2.0,因此假设您确实使用的是XSLT 2.0过程,可以在此处使用xsl:for-each-group。实际上,您可以通过Organization_ID,Organization_Code和Organization_Type的串联进行分组,但只输出每个组中的第一个元素,从而删除重复项。

试试这个XSLT

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

    <xsl:template match="root">
      <xsl:copy>
          <xsl:for-each-group select="Organization" group-by="concat(Organization_ID, '|', Organization_Code, '|', Organization_Type)">
              <xsl:apply-templates select="." />
          </xsl:for-each-group>
      </xsl:copy>
    </xsl:template>

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