1

我有一个像下面这样的 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>

朝这个方向的任何指示都会有所帮助。

谢谢

4

2 回答 2

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>
于 2013-07-03T15:47:42.080 回答
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]
于 2013-07-03T16:24:15.277 回答