2016-01-21 89 views
1

我知道有很多解决方案可以删除重复项,但这个稍有不同。如果它是重复的,我需要从输出中删除元素。 输入: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。因为它在列表中出现两次,它不应该返回2 PersonId 1113918?

<?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> 

谢谢亲切!

+2

欢迎SO模块9 key()功能。请注意,我们不是一个代码编写服务,而是一群志愿者,帮助解决认真的工作。查看[Muenchian Grouping](http://www.jenitennison.com/xslt/grouping/muenchian.html)了解XSLT 1.0或[for-each-group](http://www.saxonica.com/html/documentation) XSLT 2中的/xsl-elements/for-each-group.html)。0来计算不同的值并删除任何大于1的分组值。 – Parfait

+0

谢谢Parfait ..我用你的方向,并寻找每个组。我仍然是noob,当涉及到xslt,所以你的帮助非常感谢。 –

+0

如前所述,'for-each-group'在XSLT 2.0中可用,而不是XSLT 1.0。你的处理器是否容纳2.0? – Parfait

回答

1

我知道有很多解决方案可以删除重复,但是这一个 略有不同。我需要从如果 它是一个重复的

使用该短而简单的变换(均在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. 最后,在空(删除)模板的匹配模式中,我们检查同值元素的节点集是否有第二个元素。

注意:您可以了解更多有关<xsl:key>声明,并在我的Pluralsight的培训课程 “XSLT 2.0 and 1.0 foundations

+0

@JeromeHillman,我补充说明。 –