使用XSLT删除重复的节点

时间:2012-10-20 04:23:56

标签: xml xslt

首先我很遗憾地说“删除重复的节点不能按预期的方式工作”,即使我引用了多个线程,这些线程在一定程度上有所帮助,但我还没有达到我所期望的解决方案。

为了简要介绍我的情况,如果我的供应商和origin_country_id在后续的后代中相同,我想删除XitemSup复杂类型元素。

以下是xslt代码

<xsl:stylesheet version="1.0" exclude-result-prefixes="xsl xsd ns3"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ns3="http://xmlns.oracle.com/TSS_to_RMS/RIBXItemProcess/Supplier">
   <xsl:template match="/">
      <ns3:XItemSupDesc>
         <xsl:for-each select="//ns3:XItemSupDesc/ns3:XitemSup">             
            <xsl:if test="not(ns3:supplier=following::ns3:supplier) or not(ns3:origin_country_id=following::ns3:origin_country_id)">
                   <ns3:XitemSup>
                     <ns3:supplier>
                        <xsl:value-of select="./ns3:supplier"/>
                     </ns3:supplier>
                     <ns3:primary_supp_ind>
                        <xsl:value-of select="./ns3:primary_supp_ind"/>
                     </ns3:primary_supp_ind>
                     <ns3:origin_country_id>
                        <xsl:value-of select="./ns3:origin_country_id"/>
                     </ns3:origin_country_id>
                     <ns3:primary_country_ind>
                        <xsl:value-of select="./ns3:primary_country_ind"/>
                     </ns3:primary_country_ind>
                     <ns3:unit_cost>
                        <xsl:value-of select="./ns3:unit_cost"/>
                     </ns3:unit_cost>
                  </ns3:XitemSup>
               </xsl:if>
         </xsl:for-each>
      </ns3:XItemSupDesc>
   </xsl:template>
</xsl:stylesheet>

但如果我在xml以下申请则无法正常工作

<XItemSupDesc xmlns:ns2="http://xmlns.oracle.com/TSS_to_RMS/RIBXItemProcess/Supplier" xmlns="http://xmlns.oracle.com/TSS_to_RMS/RIBXItemProcess/Supplier">
   <ns2:XitemSup>
      <ns2:supplier>101018</ns2:supplier>
      <ns2:primary_supp_ind>N</ns2:primary_supp_ind>
      <ns2:origin_country_id>CA</ns2:origin_country_id>
      <ns2:primary_country_ind>N</ns2:primary_country_ind>
      <ns2:unit_cost>6</ns2:unit_cost>
   </ns2:XitemSup>
   <ns2:XitemSup>
      <ns2:supplier>102825</ns2:supplier>
      <ns2:primary_supp_ind>N</ns2:primary_supp_ind>
      <ns2:origin_country_id>IN</ns2:origin_country_id>
      <ns2:primary_country_ind>N</ns2:primary_country_ind>
      <ns2:unit_cost>13</ns2:unit_cost>
   </ns2:XitemSup>
   <ns2:XitemSup>
      <ns2:supplier>102825</ns2:supplier>
      <ns2:primary_supp_ind>N</ns2:primary_supp_ind>
      <ns2:origin_country_id>IN</ns2:origin_country_id>
      <ns2:primary_country_ind>N</ns2:primary_country_ind>
      <ns2:unit_cost>24</ns2:unit_cost>
   </ns2:XitemSup>
</XItemSupDesc>

我希望有人能告诉我XSLT代码出错的地方。

1 个答案:

答案 0 :(得分:1)

我建议不要使用xsl:for-each而只是覆盖身份转换。

XML输入

<XItemSupDesc xmlns:ns2="http://xmlns.oracle.com/TSS_to_RMS/RIBXItemProcess/Supplier" xmlns="http://xmlns.oracle.com/TSS_to_RMS/RIBXItemProcess/Supplier">
    <ns2:XitemSup>
        <ns2:supplier>101018</ns2:supplier>
        <ns2:primary_supp_ind>N</ns2:primary_supp_ind>
        <ns2:origin_country_id>CA</ns2:origin_country_id>
        <ns2:primary_country_ind>N</ns2:primary_country_ind>
        <ns2:unit_cost>6</ns2:unit_cost>
    </ns2:XitemSup>
    <ns2:XitemSup>
        <ns2:supplier>102825</ns2:supplier>
        <ns2:primary_supp_ind>N</ns2:primary_supp_ind>
        <ns2:origin_country_id>IN</ns2:origin_country_id>
        <ns2:primary_country_ind>N</ns2:primary_country_ind>
        <ns2:unit_cost>13</ns2:unit_cost>
    </ns2:XitemSup>
    <ns2:XitemSup>
        <ns2:supplier>102825</ns2:supplier>
        <ns2:primary_supp_ind>N</ns2:primary_supp_ind>
        <ns2:origin_country_id>IN</ns2:origin_country_id>
        <ns2:primary_country_ind>N</ns2:primary_country_ind>
        <ns2:unit_cost>24</ns2:unit_cost>
    </ns2:XitemSup>
</XItemSupDesc>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:ns2="http://xmlns.oracle.com/TSS_to_RMS/RIBXItemProcess/Supplier">
    <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="ns2:XitemSup">
        <xsl:if test="not(following::ns2:XitemSup[ns2:supplier=current()/ns2:supplier and ns2:origin_country_id=current()/ns2:origin_country_id])">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:if>       
    </xsl:template>

</xsl:stylesheet>

XML输出

<XItemSupDesc xmlns="http://xmlns.oracle.com/TSS_to_RMS/RIBXItemProcess/Supplier" xmlns:ns2="http://xmlns.oracle.com/TSS_to_RMS/RIBXItemProcess/Supplier">
   <ns2:XitemSup>
      <ns2:supplier>101018</ns2:supplier>
      <ns2:primary_supp_ind>N</ns2:primary_supp_ind>
      <ns2:origin_country_id>CA</ns2:origin_country_id>
      <ns2:primary_country_ind>N</ns2:primary_country_ind>
      <ns2:unit_cost>6</ns2:unit_cost>
   </ns2:XitemSup>
   <ns2:XitemSup>
      <ns2:supplier>102825</ns2:supplier>
      <ns2:primary_supp_ind>N</ns2:primary_supp_ind>
      <ns2:origin_country_id>IN</ns2:origin_country_id>
      <ns2:primary_country_ind>N</ns2:primary_country_ind>
      <ns2:unit_cost>24</ns2:unit_cost>
   </ns2:XitemSup>
</XItemSupDesc>

注意:如果您可以使用XSLT 2.0,则可以删除xsl:if并将模板更改为:

<xsl:template match="ns2:XitemSup[following::ns2:XitemSup[ns2:supplier=current()/ns2:supplier and ns2:origin_country_id=current()/ns2:origin_country_id]]"/>