使用xslt从xml中删除重复项

时间:2016-07-14 16:16:52

标签: xml xslt

如何使用xslt从下面的xml中删除重复项。以下是我正在使用的代码。它适用于删除重复项但无法添加相应的值

    <schedules>
       <flight>
      <Flight>
      <fno>122</fno>
      <acode>aa</acode>
        <Dest1IATA>ATL</Dest1IATA>  
        <Dest1desc>Atlanta Airport</Dest1desc>
        <Dest1town>Atlanta </Dest1town>
        <Dest2IATA>JFK</Dest2IATA>           
        <Dest2desc></Dest2desc>
        <Dest2town></Dest2town>
        <Dest2cntry></Dest2cntry>            
        <Dest3IATA>LGA</Dest3IATA>           
        <Dest3desc></Dest3desc>
        <Dest3town></Dest3town>
        <Dest3cntry></Dest3cntry>
        </Flight>
          <Flight>
      <fno>124</fno>
      <acode>aB</acode>
        <Dest1IATA>LCY</Dest1IATA>  
        <Dest1desc>LCY Airport</Dest1desc>
        <Dest1town>LCY</Dest1town>
        <Dest2IATA>DXB</Dest2IATA>           
        <Dest2desc></Dest2desc>
        <Dest2town></Dest2town>
        <Dest2cntry></Dest2cntry>            
        <Dest3IATA>LGA</Dest3IATA>           
        <Dest3desc></Dest3desc>
        <Dest3town></Dest3town>
        <Dest3cntry></Dest3cntry>
        </Flight>         
        </flight>
        </schedules>

Xslt代码:

     <xsl:for-each select="(//schedules/flight/Flight/Dest1IATA | //schedules/flight/Flight/Dest2IATA | //schedules/flight/Flight/Dest3IATA)[generate-id(.) = generate-id(key('Keycity', .))]">
      <xsl:sort select="//schedules/flight/Flight/Dest1IATA | //schedules/flight/Flight/Dest2IATA | //schedules/flight/Flight/Dest3IATA"/>

      <!--<xsl:value-of select="." />-->
      <xsl:if test="local-name() = 'Dest1IATA'  and //schedules/flight/Flight/Dest1IATA != ''">
        <Row Action="ADD">
          <xsl:value-of select="." />|<xsl:value-of select="//schedules/flight/Flight/Dest1desc" />|<xsl:value-of  select="//schedules/flight/Flight/Dest1town" />|<xsl:value-of  select="//schedules/flight/Flight/Dest1cntry" />
        </Row>
      </xsl:if>
      <xsl:if test="local-name() = 'Dest2IATA'  and //schedules/flight/Flight/Dest2IATA != ''">
        <Row Action="ADD">
          <xsl:value-of select="." />|<xsl:value-of select="//schedules/flight/Flight/Dest2desc" />|<xsl:value-of  select="//schedules/flight/Flight/Dest2town" />|<xsl:value-of  select="//schedules/flight/Flight/Dest2cntry" />
        </Row>
      </xsl:if>
      <xsl:if test="local-name() = 'Dest3IATA'  and //schedules/flight/Flight/Dest3IATA != ''">
        <Row Action="ADD">
          <xsl:value-of select="." />|<xsl:value-of select="//schedules/flight/Flight/Dest3desc" />|<xsl:value-of  select="//schedules/flight/Flight/Dest3town" />|<xsl:value-of  select="//schedules/flight/Flight/Dest3cntry" />
        </Row>
      </xsl:if>
    </xsl:for-each>

ExpectedOutput应为

ROW|Add|ATL|Atlanta Airport|
ROW|Add|JFK||
ROW|Add|LGA||
ROW|Add|LCY|LCYAirport|LCY
ROW|Add|DXB||

使用上面的代码输出

ROW|Add|ATL||
ROW|Add|JFK||
ROW|Add|LGA||
ROW|Add|LCY||
ROW|Add|DXB||

1 个答案:

答案 0 :(得分:0)

以下样式表生成的输出与您期望的非常相似。这可能是一个幸运的猜测或只是一个巧合。

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:key name="dest" match="Dest1IATA | Dest2IATA | Dest3IATA" use="." />

<xsl:template match="/schedules">
    <xsl:for-each select="(flight/Flight/Dest1IATA | flight/Flight/Dest2IATA | flight/Flight/Dest3IATA)[generate-id(.) = generate-id(key('dest', .))]">
        <xsl:text>ROW|Add|</xsl:text>
        <xsl:value-of select="." />
        <xsl:if test="self::Dest1IATA">
            <xsl:text>|</xsl:text>
            <xsl:value-of select="../Dest1desc" />
            <xsl:text>|</xsl:text>
            <xsl:value-of select="../Dest1town" />      
        </xsl:if>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each> 
</xsl:template>

</xsl:stylesheet>

应用于您的输入示例,结果将是:

ROW|Add|ATL|Atlanta Airport|Atlanta 
ROW|Add|JFK
ROW|Add|LGA
ROW|Add|LCY|LCY Airport|LCY
ROW|Add|DXB