首页 > 解决方案 > 通过保留节点的第一次出现来删除 XSLT 属性中的重复项

问题描述

我正在尝试获取 XML 的唯一值并删除重复项。我想第一次出现属性 id 相同的标签。还要注意其他不重复的射频标签不会被删除。

我的 XML 是-

<rfs>
  <rf id="key_1_fam_1">
        <data>
            <entry>
                <key>a</key>
                <value>2</value>
            </entry>
        </data>
        <cc>ccid1</cc>
        <name>as</name>
        <ref>21</ref>
         <recs>
            <rec id="key_1_fam_1_rec1">
                <data>
                    <entry>
                        <key>a</key>
                        <value>2</value>
                    </entry>
                </data>
                <type>VALID</type>
             </rec>
           </recs>

        <colour>false</colour>
    </rf>
  <rf id="key_1_fam_1">
        <data>
            <entry>
                <key>a</key>
                <value>2</value>
            </entry>
        </data>
        <cc>ccid1</cc>
        <name>as</name>
        <ref>21</ref>
         <recs>
            <rec id="key_1_fam_1_rec1">
                <data>
                    <entry>
                        <key>a</key>
                        <value>2</value>
                    </entry>
                </data>
                <type>VALID</type>
             </rec>
           </recs>

        <colour>false</colour>
    </rf> 
  <rf id="fam_2">
        <data>
            <entry>
                <key>cb</key>
                <value>2</value>
            </entry>
        </data>
        <costCentre>ccd2</costCentre>
        <name>V</name>
        <reference>31</reference>
        <recs>
            <rec id="fam_2_rec2">
                <data>
                    <entry>
                        <key>cs</key>
                        <value>aa</value>
                    </entry>
                </data>
            </rec>
        </recs>
        <colour>false</colour>
        </rf>
  <rf id="fam_3">
        <data>
            <entry>
                <key>csb</key>
                <value>2</value>
            </entry>
        </data>
        <costCentre>ccd2</costCentre>
        <name>V</name>
        <reference>34</reference>
        <recs>
            <rec id="fam_3_rec12">
                <data>
                    <entry>
                        <key>crs</key>
                        <value>aa</value>
                    </entry>
                </data>
            </rec>
        </recs>
        <colour>false</colour>
        </rf>
</rfs>

我希望输出像 -

<?xml version="1.0" encoding="UTF-8"?><rfs>
  <rf id="key_1_fam_1">
        <data>
            <entry>
                <key>a</key>
                <value>2</value>
            </entry>
        </data>
        <cc>ccid1</cc>
        <name>as</name>
        <ref>21</ref>
         <recs>
            <rec id="key_1_fam_1_rec1">
                <data>
                    <entry>
                        <key>a</key>
                        <value>2</value>
                    </entry>
                </data>
                <type>VALID</type>
             </rec>
           </recs>

        <colour>false</colour>
    </rf>
   <rf id="fam_2">
        <data>
            <entry>
                <key>cb</key>
                <value>2</value>
            </entry>
        </data>
        <costCentre>ccd2</costCentre>
        <name>V</name>
        <reference>31</reference>
        <recs>
            <rec id="fam_2_rec2">
                <data>
                    <entry>
                        <key>cs</key>
                        <value>aa</value>
                    </entry>
                </data>
            </rec>
        </recs>
        <colour>false</colour>
        </rf>
  <rf id="fam_3">
        <data>
            <entry>
                <key>csb</key>
                <value>2</value>
            </entry>
        </data>
        <costCentre>ccd2</costCentre>
        <name>V</name>
        <reference>34</reference>
        <recs>
            <rec id="fam_3_rec12">
                <data>
                    <entry>
                        <key>crs</key>
                        <value>aa</value>
                    </entry>
                </data>
            </rec>
        </recs>
        <colour>false</colour>
        </rf>
</rfs>

我尝试了以下 XSLT 并尝试了不同的值,但不确定我缺少什么。

<?xml version="1.0" ?>
<xsl:stylesheet
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:clariant="http://www.tridan.it/c"
        version="2.0">

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


<xsl:template name="removeDups">
<xsl:if test="not(. = preceding::node())">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>

<xsl:template match="rfs">
<xsl:call-template name="removeDups">
</xsl:call-template>
</xsl:template>
    
</xsl:stylesheet>

任何帮助都会非常感激,因为我是 XSLT 的新手。

标签: xmlxsltduplicatesattributesunique

解决方案


你的样式表说version="2.0"。在 XSLT 2.0 或更高版本中,您最好的选择是使用分组

XSLT 2.0

<xsl:stylesheet version="2.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="/rfs">
    <xsl:copy>
        <xsl:for-each-group select="rf" group-by="@id">
            <!-- copy the first item of current group -->
            <xsl:copy-of select="."/>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

演示:https ://xsltfiddle.liberty-development.net/pNEj9ea


推荐阅读