XSLT完全删除重复项

时间:2016-01-21 02:55:08

标签: xslt

我知道有很多解决方案可以删除重复项,但这一点略有不同。如果它是重复的,我需要从输出中删除该元素。 输入:

<SanctionList>
    <row>
        <PersonId>1000628</PersonId>
        <PersonId>1000634</PersonId>
        <PersonId>1113918</PersonId>
        <PersonId>1133507</PersonId>
        <PersonId>1113918</PersonId>
    </row>
</SanctionList>

预期输出:

<SanctionList>
    <row>
        <PersonId>1000628</PersonId>
        <PersonId>1000634</PersonId>
        <PersonId>1133507</PersonId>
    </row>
</SanctionList>

这是我尝试的但解析器为每个组返回1。不应该为PersonId 1113918返回2,因为它在列表中出现两次?

<?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"    version="2.0">
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="SanctionList">
        <xsl:for-each-group select="row" group-by="PersonId">
            <xsl:text> Count for </xsl:text>
            <xsl:value-of select="current-grouping-key()" />
                <xsl:text> is </xsl:text>
            <xsl:value-of select="count(current-group())" />
        </xsl:for-each-group>
    </xsl:template> 
</xsl:stylesheet>

非常感谢!

1 个答案:

答案 0 :(得分:1)

  

我知道有很多解决方案可以删除重复项,但是这个   略有不同。我需要从输出中删除元素if   它是重复的

使用这个简短的转换(在XSLT 2.0和XSLT 1.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:key name="kPersonByVal" match="PersonId" use="."/>

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

  <xsl:template match="PersonId[key('kPersonByVal', .)[2]]"/>
</xsl:stylesheet>

在提供的XML文档上应用转换时:

<SanctionList>
    <row>
        <PersonId>1000628</PersonId>
        <PersonId>1000634</PersonId>
        <PersonId>1113918</PersonId>
        <PersonId>1133507</PersonId>
        <PersonId>1113918</PersonId>
    </row>
</SanctionList>

产生了想要的正确结果:

<SanctionList>
   <row>
      <PersonId>1000628</PersonId>
      <PersonId>1000634</PersonId>
      <PersonId>1133507</PersonId>
   </row>
</SanctionList>

解释

  1. 用于复制现有XML文档和删除/替换/插入某些节点到复制中的众所周知的设计模式是覆盖身份规则。
  2. 在这种特殊情况下,任务是删除<PersonId>个元素。这是通过提供没有(空)主体的匹配模板来完成的。
  3. 删除标准是元素必须具有重复 - 即必须存在至少两个<PersonId>元素,具有相同的字符串值。最方便的是使用<xsl:key>声明和key()函数来获取具有相同字符串值的所有元素。
  4. 最后,在空(删除)模板的匹配模式中,我们检查等值元素的节点集是否具有第二个元素。
  5. 注意:您可以在我的Pluralsight培训课程的模块9中了解有关<xsl:key>声明和key()功能的更多信息&#34; {{3 }} &#34;