XSLT 1.0 - 根据 XML 文件中的属性值删除重复项

XSLT 1.0 - Removing duplicates based on an attribute value in a XML file

我需要一些帮助来通过 XSLT 1.0 删除重复的整体。 我已经阅读了有关此主题的所有可能答案,包括 Whosebug 上的所有建议方法(也 https://www.jenitennison.com/xslt/grouping/muenchian.xml),但我无法找出如何通过 XSLT 1.0 转换它的解决方案。

这是来源(的一部分)XML:

<?xml version="1.0" encoding="UTF-8"?>
<A>
  <B>
    <D id="PK-134" name="BBO" XorY="ADV" />
    <D id="PK-46" name="BCAMM" XorY="ADV" />
    <D id="PK-46" name="BCAmm" XorY="ADV" />
    <D id="PK-425" name="Berta" XorY="ADV" />
    <D id="PK-425" name="WWERTA" XorY="ADV" />
    <D id="PK-425" name="Werta (BW)" XorY="ADV" />
    <D id="PK-1392" name="DDex Analyzer" XorY="ADV" />
    <D id="PK-1392" name="Ddex Analyzer" XorY="ADV" />
    <D id="PK-605" name="KL DB" XorY="ADV" />
    <D id="PK-605" name="KL DB (BW)" XorY="ADV" />
    <D id="PK-142" name="CS" XorY="ADV" />
    <D id="PK-142" name="CS (FS)" XorY="ADV" />
    <D id="PK-142" name="CS FS" XorY="ADV" />
    <D id="PK-142" name="CS FS-DE" XorY="ADV" />
  </B>
</A>

所需的输出将是:

(备注:从源 XML 中找到的第一个节点应该添加到目标 XML 中,并且应该也是相关的节点,例如 <D id="PK-46" name="BCAMM" XorY="ADV" /><D id="PK-142" name="CS" XorY="ADV" />)

<?xml version="1.0" encoding="UTF-8"?>
    <A>
      <B>
        <D id="PK-134" name="BBO" XorY="ADV" />

        <D id="PK-46" name="BCAMM" XorY="ADV" />            
        <D id="PK-425" name="Berta" XorY="ADV" />            
        <D id="PK-1392" name="DDex Analyzer" XorY="ADV" />            
        <D id="PK-605" name="KL DB" XorY="ADV" />            
        <D id="PK-142" name="CS" XorY="ADV" />            
      </B>
    </A>

根据D节点内部的“id”属性去除重复项。

这是我的方法:

<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="*"/>

  <!--
  Identity transform: copy elements and attributes from input file as is
  -->
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
  </xsl:template>

  <!-- Drop <D> elements with a preceding <D> sibling that has the same @id attribute value as the current element -->
  <xsl:template match="D[preceding-sibling::D[@id = current()/@id]]"/>

</xsl:stylesheet>

不幸的是,我收到以下错误消息 (Visual Studio 2017):

error: The 'current()' function cannot be used in a pattern.

在此先感谢您的问候!

要使用身份转换和密钥,您基本上需要

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

  <xsl:key name="dup" match="D" use="@id"/>
  
  <xsl:template match="D[not(generate-id() = generate-id(key('dup', @id)[1]))]"/>