2013-07-03 80 views
1

我有一个像下面的XML,我想摆脱第二个节点,因为只有类是不同的。 我可以使用XSLT或xqy或xpath来做到这一点。删除不是相同的XML节点

<root> 
    <name> 
     <firstname>ABC</firstname> 
     <class>12</class> 
    </name> 
    <name> 
     <firstname>ABC</firstname> 
     <class>11</class> 
    </name> 

    <name> 
     <firstname>DEF</firstname> 
     <class>9</class> 
    </name> 

    <name> 
     <firstname>DEF</firstname> 
     <class>10</class> 
    </name> 
</root> 

输出预期是

<root> 
    <name> 
     <firstname>ABC</firstname> 
     <class>12</class> 
    </name> 
    <name> 
     <firstname>DEF</firstname> 
     <class>9</class> 
    </name> 
</root> 

在这个方向上的任何指针将是有益的。

感谢

+1

可以使用XSLT转换做到这一点 – robjohncox

回答

3

这是一个分组的问题,所以用XSLT 2.0使用

<xsl:template match="root"> 
    <xsl:copy> 
    <xsl:for-each-group select="name" group-by="firstname"> 
    <xsl:copy-of select="."/> 
    </xsl:for-each-group> 
    </xsl:copy> 
</xsl:template> 

用XSLT 1.0使用Muenchian分组的

<xsl:key name="k1" match="name" use="firstname"/> 

    <xsl:template match="root"> 
     <xsl:copy> 
     <xsl:for-each select="name[generate-id() = generate-id(key('k1', firstname)[1])]"> 
     <xsl:copy-of select="."/> 
     </xsl:for-each> 
     </xsl:copy> 
    </xsl:template> 
2

XQuery的,因为你可以选择每隔第二个元素:

<root>{ 
    /root/name[position() mod 2 = 1] 
}</root> 

使用XQuery更新,修改原始文件:

delete nodes //name[position() mod 2 = 0] 

如果需要比较,如果在名称前发生(因此只保留一个名字的第一个实例),改变谓词

<root>{ 
    /root/name[not(firstname = preceding-sibling::name/firstname)] 
}</root> 

各自使用XQuery更新变种

delete nodes /root/name[firstname = preceding-sibling::name/firstname]