XSLT:删除具有重复属性值的元素

XSLT: removing elements with duplicate attribute values

我有 xml,我想删除具有重复子元素 (Cost) 属性值(美元和美分与同级元素相等)的元素 (Elephant),只保留一个 (Elephant) 元素。

来源xml(这只是完整文档的一个片段):

<?xml version="1.0" encoding="UTF-8"?>
   <Day>      
         <Queue id="460402">
            <Time>4</Time>
            <Elephant>
               <Cost dollars="14" cents="5" />
            </Elephant>
            <Elephant>
               <Cost dollars="14" cents="1" />
            </Elephant>
            <Elephant>
               <Cost dollars="14" cents="6" />
            </Elephant>
            <Elephant>
               <Cost dollars="14" cents="1" />
            </Elephant>
            <Elephant>
               <Cost dollars="1" cents="46" />
            </Elephant>
            <Elephant>
               <Cost dollars="55" cents="5" />
            </Elephant>
         </Queue>
         <Queue id="460404">
            <Time>3</Time>
            <Elephant>
               <Cost dollars="7" cents="1" />
            </Elephant>
            <Elephant>
               <Cost dollars="7" cents="1" />
            </Elephant>
            <Elephant>
               <Cost dollars="7" cents="2" />
            </Elephant>
            <Elephant>
               <Cost dollars="7" cents="2" />
            </Elephant>
            <Elephant>
               <Cost dollars="114" cents="5" />
            </Elephant>
         </Queue>
         <Queue id="4666047">
            <Time>7</Time>
            <Elephant>
               <Cost dollars="14" cents="1" />
            </Elephant>
         </Queue>      
   </Day>

预期结果:

<?xml version="1.0" encoding="UTF-8"?>
   <Day>      
         <Queue id="460402">
            <Time>4</Time>
            <Elephant>
               <Cost dollars="14" cents="5" />
            </Elephant>
            <Elephant>
               <Cost dollars="14" cents="1" />
            </Elephant>
            <Elephant>
               <Cost dollars="14" cents="6" />
            </Elephant>           
            <Elephant>
               <Cost dollars="1" cents="46" />
            </Elephant>
            <Elephant>
               <Cost dollars="55" cents="5" />
            </Elephant>
         </Queue>
         <Queue id="460404">
            <Time>3</Time>
            <Elephant>
               <Cost dollars="7" cents="1" />
            </Elephant>
            <Elephant>
               <Cost dollars="7" cents="2" />
            </Elephant>
            <Elephant>
               <Cost dollars="114" cents="5" />
            </Elephant>
         </Queue>
         <Queue id="4666047">
            <Time>7</Time>
            <Elephant>
               <Cost dollars="14" cents="1" />
            </Elephant>
         </Queue>      
   </Day>

我尝试 运行 这个 xslt 转换,但它不能正常工作(丢失的数据比应该的多):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="Elephant[Cost/@dollars= following-sibling:: Elephant/Cost/@dollars and Cost/@cents= following-sibling:: Elephant/Cost/@cents]"/>
</xsl:stylesheet>

找到解决方案:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="2.0">

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>

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

  <xsl:template match="Queue">
      <xsl:copy>
          <xsl:apply-templates select="*[not(self::Elephant)]|@*"/>
          <xsl:for-each-group select="Elephant" group-by="Cost/(@dollars + 0.01 * @cents)">
              <xsl:apply-templates select="."/>
          </xsl:for-each-group>
      </xsl:copy>
  </xsl:template>
</xsl:stylesheet>