2014-01-23 109 views
0

我有一個傳入的XML是這樣的:XSLT檢查重複值

<comm> 
<source id ="1">TV</source> 
<source id ="2">Radio</source> 
<source id ="3">TV</source> 
<source id ="4">Computer</source> 
</comm> 

我需要一個XSLT使輸出的XML是這樣的:

<comm> 
<type id ="1">TV</source> 
<type id ="2">Radio</source> 
<type id ="4">Computer</source> 
</comm> 

基本上我想要的XSLT要經過每<source>元素並創建一個<type>元素。但是,如果<type>元素的值已經存在,XSLT將跳過創建元素。 舉個例子,如果你看一下傳入的XML出現兩次的「TV」值;所以XSLT將只創建一次具有TV值的元素。

我有一個很難搞清楚了這一點。我正在使用XSLT 2.0。

我試圖通過動態更新變量,然後移除重複值來做到這一點。但XSLT不能更改變量。

+0

的可能重複的[XSLT刪除重複(http://stackoverflow.com/questions/5509424/xslt-removing-duplicates) –

回答

0

這在XSLT 2.0中非常簡單,使用xsl:for-each-group,儘管您只需要選擇每個組中的第一個元素。

要檢查通過他們的文本值的元素,因此,所有你需要做的就是這個

<xsl:for-each-group select="source" group-by="text()"> 

而要改變只是通過簡單的templte

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

試試這個XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/*"> 
     <xsl:copy> 
      <xsl:for-each-group select="source" group-by="text()"> 
       <xsl:apply-templates select="."/> 
      </xsl:for-each-group> 
     </xsl:copy> 
    </xsl:template> 

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

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

請注意,使用了identity template的,複製現有的元素。

請仔細閱讀http://www.xml.com/lpt/a/1314以獲得大量有關xsl:for-each-group的幫助信息。