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

XSLT1.0中如何在重复查询中筛选唯一Selected属性值

XSLT1.0实现AllOptions对应唯一Selected值输出

示例XML数据

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <AllOptions Id="123"></AllOptions>
    <AllOptions Id="456"></AllOptions>
    <AllOptions Id="789"></AllOptions>
    <AllOptions Id="789"></AllOptions>
    <AllOptions Id="101"></AllOptions>
    <SelectedOptions>
        <SelectedOption Id="101" Selected="No"></SelectedOption>
        <SelectedOption Id="789" Selected="Yes"></SelectedOption>
        <SelectedOption Id="789" Selected="No"></SelectedOption>
        <SelectedOption Id="123" Selected="No"></SelectedOption>
        <SelectedOption Id="456" Selected="No"></SelectedOption>
    </SelectedOptions>
</root>

问题背景

使用仅支持XSLT1.0的工具结合XSLFO做数据转换,现有模板逻辑为:

  • 遍历<AllOptions>节点
  • 内部循环匹配同@Id的<SelectedOption>节点,要求每个<AllOptions>对应唯一的@Selected值输出

现有模板代码:

<xsl:template name="ShowOptions">
    <xsl:for-each select="/root/AllOptions">
        <fo:block><xsl:value-of select="@Id"/></fo:block>
        <xsl:for-each select="../SelectedOptions/SelectedOption[@Id = current()/@Id]">
            <fo:block> <xsl:value-of select="@Selected"/> </fo:block>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

当前输出问题

同一@Id的<AllOptions>会重复输出所有匹配的@Selected值,例如:

123 
   No
456
   No
789
   Yes
   No
789
   Yes
   No
101
   No

期望输出

每个<AllOptions>对应唯一的@Selected值,相同@Id的<AllOptions>分别对应不同的@Selected状态:

123 
   No
456
   No
789
   Yes
789
   No
101
   No

解决方案

利用XSLT1.0的Muenchian分组实现去重,同时结合节点位置匹配,为每个同@Id的<AllOptions>分配唯一的@Selected值:

<xsl:template name="ShowOptions">
    <!-- 定义复合分组键:按@Id和@Selected组合,确保每个组合唯一 -->
    <xsl:key name="selected-group" match="SelectedOption" use="concat(@Id, '|', @Selected)"/>

    <xsl:for-each select="/root/AllOptions">
        <fo:block><xsl:value-of select="@Id"/></fo:block>
        
        <!-- 记录当前AllOptions在同Id节点中的位置(从1开始计数) -->
        <xsl:variable name="current-index" select="count(preceding-sibling::AllOptions[@Id = current()/@Id]) + 1"/>
        <!-- 筛选当前Id下所有唯一的SelectedOption项 -->
        <xsl:variable name="unique-selected" select="../SelectedOptions/SelectedOption[
            @Id = current()/@Id 
            and generate-id() = generate-id(key('selected-group', concat(@Id, '|', @Selected))[1])
        ]"/>

        <!-- 根据当前位置输出对应的Selected值 -->
        <xsl:if test="$unique-selected[$current-index]">
            <fo:block> <xsl:value-of select="$unique-selected[$current-index]/@Selected"/> </fo:block>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

逻辑说明

  1. Muenchian分组:通过<xsl:key>创建@Id+@Selected的复合键,将相同组合的<SelectedOption>归为一组,利用generate-id()筛选出每组的第一个节点,实现去重。
  2. 位置匹配:计算当前<AllOptions>在同@Id节点中的位置,从去重后的SelectedOption列表中取出对应位置的项,确保每个<AllOptions>只输出一个@Selected值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 17:42:27