通过保留第一次出现的节点来删除 XSLT 属性中的重复项
Posted
技术标签:
【中文标题】通过保留第一次出现的节点来删除 XSLT 属性中的重复项【英文标题】:Remove duplicate in the attribute of an XSLT by keeping first occurrence of the node 【发布时间】:2021-11-12 00:46:53 【问题描述】:我正在尝试获取 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 的新手。
【问题讨论】:
【参考方案1】:您的样式表显示version="2.0"
。在 XSLT 2.0 或更高版本中,您最好的选择是使用grouping:
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
【讨论】:
以上是关于通过保留第一次出现的节点来删除 XSLT 属性中的重复项的主要内容,如果未能解决你的问题,请参考以下文章