2010-12-10 20 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 
相关问题