xslt - 如何根据层次结构级别删除重复项?

标签 xslt duplicates duplicate-removal

我具有以下XML结构:

<node name="A">
  <node name="B">
    <node name="C"/>
    <node name="D"/>
    <node name="E"/>
  </node>
  <node name="D"/>
  <node name="E"/>
</node>

我需要获取所有叶节点。我使用// node [not(node)]来获取那些。现在,我需要通过保留层次结构中更深的元素来删除重复项。我怎么做?

最佳答案

此转换:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="vallLeaves" select="//node()[not(node())]"/>

 <xsl:template match="/">
$vallLeaves:
     <xsl:copy-of select="$vallLeaves"/>

$vallDistinctLeaves:    
     <xsl:for-each select="$vallLeaves">
       <xsl:if test=
       "generate-id()
        =
         generate-id($vallLeaves[@name
                                =
                                 current()/@name
                               ]
                                  [1]
                   )
     ">
         <xsl:copy-of select="."/>
       </xsl:if>
     </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时:
<node name="A">
  <node name="B">
    <node name="C"/>
    <node name="D"/>
    <node name="E"/>
  </node>
  <node name="D"/>
  <node name="E"/>
</node>

产生所需的正确结果:
$vallLeaves:
     <node name="C"/>
<node name="D"/>
<node name="E"/>
<node name="D"/>
<node name="E"/>

$vallDistinctLeaves:    
     <node name="C"/>
<node name="D"/>
<node name="E"/>

II。 XSLT 2.0解决方案:
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="vallLeaves" select="//node()[not(node())]"/>
    <xsl:variable name="vallDistinctLeaves" as="element()*">
      <xsl:for-each-group select="$vallLeaves" group-by="@name">
       <xsl:sequence select="."/>
      </xsl:for-each-group>
    </xsl:variable>

 <xsl:template match="/">
$vallLeaves:
     <xsl:sequence select="$vallLeaves"/>

$vallDistinctLeaves:    
     <xsl:sequence select="$vallDistinctLeaves"/>
 </xsl:template>
</xsl:stylesheet>

将此转换应用于相同的XML文档(如上)时,使用会产生相同的正确结果:
$vallLeaves:
     <node name="C"/>
<node name="D"/>
<node name="E"/>
<node name="D"/>
<node name="E"/>

$vallDistinctLeaves:    
     <node name="C"/>
<node name="D"/>
<node name="E"/>

关于xslt - 如何根据层次结构级别删除重复项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3854654/

相关文章:

xslt - 如何使 xsl 转换缩进输出?

objective-c - 检查 NSMutableArray 上是否有重复的 NSString

java - 在这种情况下有没有办法完全避免重复代码?

xslt - 在组起始中使用变量

.net - 在xslt,.net中为应用模板选择传递参数

javascript - 如何合并/推送 Javascript 数组中的重复值

从向量中删除至少 x 次不重复的值

javascript - 删除排序数组中的重复项

mysql - 使用连接从表中删除重复行

html - XSLT 转换从混合内容中移除 HTML 元素