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

XSLT中无法获取XML特定Build节点的car属性去重值求助

问题根源

你遇到的问题出在preceding::car这个轴的使用上——它会匹配整个文档中当前节点之前的所有<car>元素,包括第一个<Build>里的那些。第二个<Build>里的<car value="xyz"/>,它的preceding::car已经包含第一个Build中的<car value="xyz"/>了,所以not(@value = preceding::car/@value)会直接把这个xyz排除,最后只剩mno能通过过滤。

修复方案

我们需要把去重的范围限定在当前<Build>节点内部,而不是整个文档。可以修改for-each的选择条件,只对比当前<Build>下<Test>节点内、当前<car>之前的兄弟节点:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="Results">
    <xsl:apply-templates select="Build[2]" />
  </xsl:template>

  <xsl:template match="Build">
    <html>
      <body>
        <!-- 只在当前Build的Test下,筛选非空且未在当前节点之前出现过的car -->
        <xsl:for-each select="Test/car[@value!='' and not(@value = preceding-sibling::car/@value)]">
          <xsl:sort select="@value" />
          <li>
            <xsl:value-of select='@value' />
          </li>
        </xsl:for-each>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

如果你觉得preceding-sibling的上下文不够直观,也可以用另一种写法,明确限定范围在当前<Test>的子节点中:

<xsl:for-each select="Test/car[@value!='']">
  <xsl:if test="not(@value = ../car[position() &lt; current()/position()]/@value)">
    <xsl:sort select="@value" />
    <li>
      <xsl:value-of select='@value' />
    </li>
  </xsl:if>
</xsl:for-each>
验证结果

用修改后的代码处理你的XML,会得到符合预期的输出:

<html>
  <body>
    <li>mno</li>
    <li>xyz</li>
  </body>
</html>

(注:因为用了<xsl:sort>,所以mno排在xyz前面;如果需要保持原文档中出现的顺序,去掉<xsl:sort>标签即可)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:37:55