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

如何通过XSLT遍历两个变量并生成不含重复ID的新变量?

问题:筛选$A中未在$B出现的asset节点

我有两个XSLT变量:

<xsl:variable name="A">
    <asset id="111">[...]</asset>
    <asset id="222">[...]</asset>
</xsl:variable>

<xsl:variable name="B">
    <asset id="333">[...]</asset>
    <asset id="444">[...]</asset>
    <asset id="111">[...]</asset>
    <asset id="555">[...]</asset>
    <asset id="999">[...]</asset>
</xsl:variable>

需求:取出$A中每个asset节点的id值,检查该id是否未在$B的asset节点中出现。若未出现,则将$A中的当前asset节点复制到新变量$Final中。正确结果应该是$Final仅包含id为222的asset节点。

我尝试了以下代码,无法实现需求:

<xsl:variable name="Final">
    <xsl:for-each select="$A/asset">
        <xsl:variable name="presentXML">
            <xsl:copy-of select="."/>
        </xsl:variable>
        <xsl:variable name="presentID">
            <xsl:value-of select="./@id"/>
        </xsl:variable>

        <xsl:for-each select="$B/asset">
            <xsl:variable name="pastID">
                <xsl:value-of select="./@id"/>
            </xsl:variable>

            <xsl:choose>
                <xsl:when test="$presentID != $pastID">
                    <xsl:copy-of select="$presentXML"/>
                </xsl:when>
                <xsl:otherwise>

                </xsl:otherwise >
            </xsl:choose>
        </xsl:for-each>
    </xsl:for-each>
</xsl:variable>

问题分析

你的代码逻辑错误在于:遍历$B的每个asset时,只要当前$A的asset id和单个$B的asset id不等就执行复制。这会导致同一个$A的asset被多次复制(比如id=111的asset,会和$B中id为333、444、555、999的asset都触发不等判断,从而被复制4次),而我们需要的是当$A的asset id在$B中完全不存在时才复制该节点。

正确实现方法

方法1:XSLT 1.0兼容写法

XSLT 1.0不支持直接的节点序列比较,可通过判断$B中是否存在匹配id的asset节点来实现:

<xsl:variable name="Final">
    <!-- 遍历$A中的每个asset -->
    <xsl:for-each select="$A/asset">
        <!-- 保存当前asset的id,避免多次查询 -->
        <xsl:variable name="currentId" select="@id"/>
        <!-- 判断$B中是否没有id等于$currentId的asset -->
        <xsl:if test="not($B/asset[@id = $currentId])">
            <!-- 复制当前asset节点到$Final -->
            <xsl:copy-of select="."/>
        </xsl:if>
    </xsl:for-each>
</xsl:variable>

方法2:XSLT 2.0+简洁写法

XSLT 2.0及以上版本支持节点序列的直接比较,写法更简洁:

<xsl:variable name="Final">
    <!-- 直接筛选$A中id不在$B的asset id序列中的节点 -->
    <xsl:copy-of select="$A/asset[not(@id = $B/asset/@id)]"/>
</xsl:variable>

两种方法最终都会生成仅包含id为222的asset节点的$Final变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 02:15:00