在XML中删除不太相同的节点

时间:2013-07-03 15:41:09

标签: xslt xpath xquery

我有一个类似下面的XML,我想摆脱第二个节点,因为只有类不同。 我可以使用XSLT或xqy或xpath执行此操作。

<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>

这方面的任何指示都会有所帮助。

由于

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分: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 Update

各自的变体
delete nodes /root/name[firstname = preceding-sibling::name/firstname]