2010-12-10 16 views
1

我的意圖是在一個XSL中,只顯示具有共同值的一組節點的文本節點。例如,我有以下XML:在XSL中,執行類似於C#中的操作:list.Select(x => x.ID).Distinct();

<Nodes> 
    <Node att="1">A</Node> 
    <Node att="1">B</Node> 
    <Node att="2">C</Node> 
    <Node att="2">D</Node> 
    <Node att="3">E</Node> 
</Nodes> 

我的輸出結果是:「ACE」。

我不知道屬性「att」的值是什麼。它可以是任何字符串。

任何建議將不勝感激!

+0

這裏有一個非常類似的問題,有很多答案:http://stackoverflow.com/questions/399204/xslt-distinct-elements-and-分組 – 2010-12-10 23:03:27

+0

「ACE」輸出將用於每個獨立值的第一個(文檔順序)。請做澄清。 – 2010-12-10 23:05:30

+0

好問題,+1。查看我的答案可能是最簡單和最短的解決方案 - XPath單行程式。 :) – 2010-12-11 00:10:57

回答

1

這甚至可以在一個XPath表達式剛剛做:

/*/*[not(@att=preceding-sibling::*/@att)]/text() 

所以,在XSLT包裹它給我們

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

<xsl:template match="/"> 
    <xsl:copy-of select="/*/*[not(@att=preceding-sibling::*/@att)]/text()"/> 
</xsl:template> 
</xsl:stylesheet> 

和應用這對提供的XML文件:

<Nodes> 
    <Node att="1">A</Node> 
    <Node att="1">B</Node> 
    <Node att="2">C</Node> 
    <Node att="2">D</Node> 
    <Node att="3">E</Node> 
</Nodes> 

產生想要的,正確的結果

ACE 
+0

+1最佳答案。 – Flack 2010-12-11 01:24:52

+0

我真的很喜歡你的答案,但只是爲了確定,是否需要對節點進行排序才能使其工作? – Olyan 2010-12-13 14:39:13

+0

@Olan:不,假定/不需要排序。 XPath表達式選擇具有特定不同值的第一個節點(按文檔順序)。 – 2010-12-13 16:34:39

0

這是一個常見問題。見http://www.jenitennison.com/xslt/grouping/muenchian.html

該XSLT代碼:

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

<xsl:key name="criteria" match="/Nodes/Node" use="@att"/> 

<xsl:template match="Nodes"> 
    <xsl:copy> 
     <xsl:apply-templates select="Node[generate-id() = generate-id(key('criteria', @att))]"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="Node"> 
    <xsl:copy-of select="."/> <!-- Or other actions --> 
</xsl:template> 

</xsl:stylesheet> 

將提供所需的(如果我理解正確的)輸出:

<?xml version="1.0" encoding="UTF-8"?> 
<Nodes> 
    <Node att="1">A</Node> 
    <Node att="2">C</Node> 
    <Node att="3">E</Node> 
</Nodes> 

它也將與像輸入工作,例如:

<Nodes> 
    <Node att="someRandomString">A</Node> 
    <Node att="1aeawe">B</Node> 
    <Node att="someRandomString">C</Node> 
    <Node att="sfdf">D</Node> 
    <Node att="">E</Node> 
    <Node att="sfdf">F</Node> 
</Nodes> 

輸出結果爲:

<?xml version="1.0" encoding="UTF-8"?> 
<Nodes> 
    <Node att="someRandomString">A</Node> 
    <Node att="1aeawe">B</Node> 
    <Node att="sfdf">D</Node> 
    <Node att="">E</Node> 
</Nodes> 
0

這一點樣式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 
    <xsl:key name="kNodeByAtt" match="Node" use="@att"/> 
    <xsl:template match="Node[count(.|key('kNodeByAtt',@att)[1])!=1]"/> 
</xsl:stylesheet> 

輸出:

ACE 

編輯:只是爲了好玩的XPath 2.0解決方案

string-join((/Nodes/Node)[index-of(/Nodes/Node/@att,@att)[1]],'') 

結果:

ACE 
相關問題