首页 > 解决方案 > 使用 XSLT 删除重复问题

问题描述

我有以下 XML。`

<?xml version="1.0" encoding="UTF-8"?>
<ns0:Rates xmlns:ns0="urn:test.com:Bloomberg:ExchangeRate">
   <ExchangeRates>
      <Header>
         <App>FxApp</App>
         <Entity>Rate</Entity>
         <ProcessedDate>20200820</ProcessedDate>
      </Header>
      <ExchangeRate>
         <RateType>Corporate</RateType>
         <From>USD</From>
         <To>CHF</To>
         <ValidFromDate>20200820</ValidFromDate>
         <Conversion>.91</Conversion>
      </ExchangeRate>
      <ExchangeRate>
         <RateType>Corporate</RateType>
         <From>INR</From>
         <To>EUR</To>
         <ValidFromDate>20200820</ValidFromDate>
         <Conversion>0.11</Conversion>
      </ExchangeRate>
      <ExchangeRate>
         <RateType>Corporate</RateType>
         <From>USD</From>
         <To>CHF</To>
         <ValidFromDate>20200820</ValidFromDate>
         <Conversion>0.91029</Conversion>
      </ExchangeRate>
   </ExchangeRates>
</ns0:Rates>

在这个费率 XML 中,我们有一个 Header,然后是 ExchangeRate 集。从这组中,我们需要删除重复的。对于这种情况,美元兑瑞郎汇率转换为 0.91029。所以预期的结果如下。

<?xml version="1.0" encoding="UTF-8"?>
<ns0:Rates xmlns:ns0="urn:test.com:Bloomberg:ExchangeRate">
   <ExchangeRates>
      <Header>
         <App>FxApp</App>
         <Entity>Rate</Entity>
         <ProcessedDate>20200820</ProcessedDate>
      </Header>
      <ExchangeRate>
         <RateType>Corporate</RateType>
         <From>USD</From>
         <To>CHF</To>
         <ValidFromDate>20200820</ValidFromDate>
         <Conversion>.91</Conversion>
      </ExchangeRate>
      <ExchangeRate>
         <RateType>Corporate</RateType>
         <From>INR</From>
         <To>EUR</To>
         <ValidFromDate>20200820</ValidFromDate>
         <Conversion>0.11</Conversion>
      </ExchangeRate>
   </ExchangeRates>
</ns0:Rates>

我正在尝试使用以下 XSLT 逻辑。

<xsl:stylesheet version="1.0" exclude-result-prefixes="xsl xsd" xmlns:ns="urn:test.com:Bloomberg:ExchangeRate" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <xsl:template match="/">
      <ns:Rates>
         <xsl:for-each select="/ns:Rates/ExchangeRates/ExchangeRate[not(RateType=following::RateType)]">
            <xsl:sort select="./ValidFromDate" order="ascending"/>
            <ExchangeRate>
               <xsl:copy-of select="./RateType"/>
               <xsl:copy-of select="./From"/>
               <xsl:copy-of select="./To"/>
               <xsl:copy-of select="./ValidFromDate"/>
               <xsl:copy-of select="./Conversion"/>
            </ExchangeRate>
         </xsl:for-each>
      </ns:Rates>
   </xsl:template>
</xsl:stylesheet>

这样,输出就会以随机方式运行,并且还会删除标头。像下面这样的东西是我得到的。由于某种原因,INR-EUR 货币对也被意外移除。

<?xml version="1.0" encoding="UTF-8"?>
<ns0:Rates xmlns:ns0="urn:test.com:Bloomberg:ExchangeRate">
   <ExchangeRates>
      <ExchangeRate>
         <RateType>Corporate</RateType>
         <From>USD</From>
         <To>CHF</To>
         <ValidFromDate>20200820</ValidFromDate>
         <Conversion>.91</Conversion>
      </ExchangeRate>
   </ExchangeRates>
</ns0:Rates>

任何建议或修复将不胜感激。

标签: xmlxsltduplicates

解决方案


我会对您想要的选定字段进行分组。然后我会为每个组做一个,这样重复的就会被消除。

<xsl:stylesheet version="1.0" exclude-result-prefixes="xsl xsd" xmlns:ns="urn:test.com:Bloomberg:ExchangeRate" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    
    <xsl:key name="GroupRate" match="/ns:Rates/ExchangeRates/ExchangeRate" use="concat(RateType, From, To)" />
    
    
    <xsl:template match="/">
        <ns:Rates>
            <Header>
                <App><xsl:value-of select="/ns:Rates/ExchangeRates/Header/App"/></App>
                <Entity><xsl:value-of select="/ns:Rates/ExchangeRates/Header/Entity"/></Entity>
                <ProcessedDate><xsl:value-of select="/ns:Rates/ExchangeRates/Header/ProcessedDate"/></ProcessedDate>
            </Header>
        
            <xsl:for-each select="/ns:Rates/ExchangeRates/ExchangeRate[generate-id() = generate-id(key('GroupRate', concat(RateType, From, To))[1])]">
                <ExchangeRate>
                    <xsl:copy-of select="node()"/>
                </ExchangeRate>
            </xsl:for-each>
        </ns:Rates>
    </xsl:template>
</xsl:stylesheet>

推荐阅读