2017-04-14 201 views
1

我試圖從列表中獲取非重複節點值。我嘗試了很多建議,但沒有爲我工作。 這是我的源XMLXSLT選擇非重複節點值

<Records> 
    <Record> 
    <Files> 
     <File> 
     <Name>A</Name> 
     </File> 
     <File> 
     <Name>B</Name> 
     </File> 
     <File> 
     <Name>B</Name> 
     </File> 
    </Files> 
    </Record> 
    <Record> 
    <Files> 
     <File> 
     <Name>A</Name> 
     </File> 
     <File> 
     <Name>B</Name> 
     </File> 
     <File> 
     <Name>C</Name> 
     </File> 
     <File> 
     <Name>C</Name> 
     </File> 
    </Files> 
    </Record> 
</Records> 

輸出我要找應該看起來像這樣

A,B | A,B,C 

第一個逗號分隔集的文本是從第一條記錄和第二組(後「|」)是從第二個記錄。 (分隔符的位置,空間等等......是不是我的問題,這是去除重複的)

代碼,我現在看起來是這樣

<xsl:key name="NameId" match="Name" use="." /> 

<xsl:for-each select="Records/Record"> 
    <xsl:call-template name="doeach_record"/> 
    <xsl:text>|</xsl:text> 
</xsl:for-each> 

<xsl:template name="doeach_record"> 
    <xsl:for-each select="Files/File"> 
    <xsl:if test="generate-id(Name) = generate-id(key('NameId', Name)[1])"> 
     <xsl:value-of select="Name"/> 
    </xsl:if> 
    <xsl:text>,</xsl:text> 
    </xsl:for-each> 
</xsl:template> 

,從第一個記錄刪除重複,第二記錄它不選擇在第一個記錄中找到的名稱值。 我得到的輸出是這樣的

A,B | ,,C 

回答

1

有XSLT 2.0自2007年以來各種實施方案的像撒克遜9,XmlPrime,Altova公司在那裏你可以使用<xsl:template match="Record"><xsl:value-of select="distinct-values(Files/File/Name)" separator=","/></xsl:template>。如果您確實被限制在XSLT 1.0中,那麼您需要定義一個密鑰,該密鑰將祖先Record的生成標識與Name(例如, <xsl:key name="unique" match="File/Name" use="concat(generate-id(ancestor::Record), '|', .)"/>,那麼你可以使用通常的XSLT 1.0密鑰基於Muenchian分組/不同值方法。

1

正如馬丁所說,在XSLT 2.0中,distinct-values()是你的朋友。

這是XSLT 2.0的稍微不同的方法。這包括排序,以防輸入XML尚未按字母順序排列。

​​