You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XSLT多条件去重需求:提取v=A的v1/v2唯一组合节点ID

没问题,我帮你搞定这个需求!首先咱们得明确核心要求:筛选出所有v值为A的节点,并且每个v1和v2的组合只保留一个对应的id,最终输出2、3、4、6、7这些id。

首先,先把你没写完的XML补全(模拟重复和非A的场景),方便测试:

<root>
  <node>
    <v>A</v>
    <id>2</id>
    <v1>S</v1>
    <v2>S</v2>
  </node>
  <node>
    <v>A</v>
    <id>3</id>
    <v1>S</v1>
    <v2>S1</v2>
  </node>
  <node>
    <v>A</v>
    <id>4</id>
    <v1>S2</v1>
    <v2>S</v2>
  </node>
  <node>
    <v>A</v>
    <id>5</id>
    <v1>S</v1>
    <v2>S</v2> <!-- 和id2的v1/v2重复,会被过滤 -->
  </node>
  <node>
    <v>A</v>
    <id>6</id>
    <v1>S3</v1>
    <v2>S2</v2>
  </node>
  <node>
    <v>A</v>
    <id>7</id>
    <v1>S1</v1>
    <v2>S3</v2>
  </node>
  <node>
    <v>B</v>
    <id>8</id>
    <v1>S</v1>
    <v2>S</v2> <!-- v不是A,直接排除 -->
  </node>
</root>

接下来分两种情况给你解决方案:


方案1:XSLT 1.0 (兼容旧版处理器)

XSLT1.0里常用Muenchian分组来实现去重,核心是用<xsl:key>定义分组规则,然后筛选每组的第一个节点:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" encoding="UTF-8"/>

  <!-- 定义分组键:仅匹配v=A的节点,键是v1和v2的拼接(用|做分隔符避免冲突) -->
  <xsl:key name="group-by-v1v2" match="node[v='A']" use="concat(v1, '|', v2)"/>

  <xsl:template match="/">
    <!-- 遍历每个分组的第一个节点 -->
    <xsl:for-each select="root/node[v='A'][count(. | key('group-by-v1v2', concat(v1, '|', v2))[1]) = 1]">
      <!-- 给除了第一个的id加逗号分隔 -->
      <xsl:if test="position() > 1">
        <xsl:text>, </xsl:text>
      </xsl:if>
      <xsl:value-of select="id"/>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

运行后输出:2, 3, 4, 6, 7,完全符合预期。


方案2:XSLT 2.0+ (语法更简洁)

如果你的处理器支持XSLT2.0及以上(比如Saxon),可以直接用<xsl:for-each-group>语法,逻辑更直观:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" encoding="UTF-8"/>

  <xsl:template match="/">
    <!-- 按v1+v2的组合分组,仅处理v=A的节点 -->
    <xsl:for-each-group select="root/node[v='A']" group-by="concat(v1, '|', v2)">
      <!-- 输出每组第一个节点的id,加逗号分隔 -->
      <xsl:if test="position() > 1">
        <xsl:text>, </xsl:text>
      </xsl:if>
      <xsl:value-of select="current-group()[1]/id"/>
    </xsl:for-each-group>
  </xsl:template>
</xsl:stylesheet>

这个方案的输出和上面完全一致,写法更简洁易懂。


补充说明:用|作为v1和v2的分隔符是为了避免比如v1='AB'+v2='C'和v1='A'+v2='BC'这种拼接后字符串相同的情况,如果你确定v1和v2里不会出现|,这个分隔符就很安全;如果可能出现,换一个不会出现的字符就行(比如特殊符号&#x1F600;,或者用更复杂的拼接逻辑)。

内容的提问来源于stack exchange,提问作者rmm19433

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:45:33