如何使用xslt删除重复的xml节点?

如何使用xslt删除重复的xml节点?,xml,xslt,Xml,Xslt,我想使用xslt删除所有变量完全匹配时的重复项 在此xml中,应该删除节点3,因为它是节点1的完美副本 <root> <trips> <trip> <got_car>0</got_car> <from>Stockholm, Sweden</from> <to>Gothenburg, Sweden</to>

我想使用xslt删除所有变量完全匹配时的重复项

在此xml中,应该删除节点3,因为它是节点1的完美副本

<root> 
    <trips> 
      <trip> 
        <got_car>0</got_car> 
        <from>Stockholm, Sweden</from> 
        <to>Gothenburg, Sweden</to> 
        <when_iso>2010-12-06 00:00</when_iso> 
      </trip>
      <trip> 
        <got_car>0</got_car> 
        <from>Stockholm, Sweden</from> 
        <to>New york, USA</to> 
        <when_iso>2010-12-06 00:00</when_iso> 
      </trip>
      <trip> 
        <got_car>0</got_car> 
        <from>Stockholm, Sweden</from> 
        <to>Gothenburg, Sweden</to> 
        <when_iso>2010-12-06 00:00</when_iso> 
      </trip>
      <trip> 
        <got_car>1</got_car> 
        <from>Test, Duncan, NM 85534, USA</from> 
        <to>Test, Duncan, NM 85534, USA</to> 
        <when_iso>2010-12-06 00:00</when_iso> 
      </trip> 
    <trips> 
<root>

0
瑞典斯德哥尔摩
瑞典哥德堡
2010-12-06 00:00 
0
瑞典斯德哥尔摩
美国纽约
2010-12-06 00:00 
0
瑞典斯德哥尔摩
瑞典哥德堡
2010-12-06 00:00 
1.
Test,美国新墨西哥州邓肯85534
Test,美国新墨西哥州邓肯85534
2010-12-06 00:00 

如果您使用的是XSLT 1.0,以下答案可能会有所帮助: . 使用XSLT 2.0更容易,但这并不是普遍部署的

此代码:

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

<xsl:key name="trip-tth" match="/root/trips/trip" use="concat(got_car, '+', from, '+', to, '+', when_iso)"/>

<xsl:template match="root/trips">   
    <xsl:copy>
        <xsl:apply-templates select="trip[generate-id(.) = generate-id( key ('trip-tth', concat(got_car, '+', from, '+', to, '+', when_iso) ) )]"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="trip">
    <xsl:copy-of select="."/>
</xsl:template>

</xsl:stylesheet>

我会成功的


它利用了这样一个事实,即应用于键的generate-id()将获取与给定条件匹配的第一个节点的id。在我们的例子中,标准是每个trip子元素的连接值。

为了更好地设计,此样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="kTripByContent" match="trip"
             use="concat(got_car,'+',from,'+',to,'+',when_iso)"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="trip[generate-id() !=
                              generate-id(key('kTripByContent',
                                              concat(got_car,'+',
                                                     from,'+',
                                                     to,'+',
                                                     when_iso))[1])]"/>
</xsl:stylesheet>

输出:

<root>
    <trips>
        <trip>
            <got_car>0</got_car>
            <from>Stockholm, Sweden</from>
            <to>Gothenburg, Sweden</to>
            <when_iso>2010-12-06 00:00</when_iso>
        </trip>
        <trip>
            <got_car>0</got_car>
            <from>Stockholm, Sweden</from>
            <to>New york, USA</to>
            <when_iso>2010-12-06 00:00</when_iso>
        </trip>
        <trip>
            <got_car>1</got_car>
            <from>Test, Duncan, NM 85534, USA</from>
            <to>Test, Duncan, NM 85534, USA</to>
            <when_iso>2010-12-06 00:00</when_iso>
        </trip>
    </trips>
</root>

0
瑞典斯德哥尔摩
瑞典哥德堡
2010-12-06 00:00
0
瑞典斯德哥尔摩
美国纽约
2010-12-06 00:00
1.
Test,美国新墨西哥州邓肯85534
Test,美国新墨西哥州邓肯85534
2010-12-06 00:00

可能重复@Flack:通常你的答案并不完全正确。每当使用串接作为键时,在这个串接中包含分隔字符串是安全和必要的,以避免将
concat('A','BC')
concat('AB','C')
视为“相同”。实际上,您能解释一下我如何为每个数组将新数据放入A中吗?@Dimitre Novatchev,感谢您的有用评论。我已经为未来的读者编辑了我的回复。@Kristofer Nolgren,如果我没有弄错你的观点,你想对每个模板使用而不是应用模板吗?好的,xpath表达式将是相同的。@Flack:这个答案有价值,因为键连接(一旦它跟随@Dimitre备注…),但样式表的其余部分有许多错误:键/@match模式的绝对路径,失去
根元素,推式样式模板应用于以后的显式
xsl:copy
。。。