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

XSLT3.0中使用累加器执行Lookup无法返回值的问题

XSLT 3.0流处理Lookup返回空值的问题解决建议

问题说明

有一份来自两个数据源的聚合XML输入,使用包含三个累加器的XSLT 3.0代码进行Lookup操作,但Lookup返回空值,无法得到预期结果。

聚合输入XML

<?xml version="1.0" encoding="utf-8"?>
<aggregate-data>
<weci:Workers_Effective_Stack xmlns:weci="urn:com.workday/weci">
    <weci:Worker>
        <weci:Worker_Summary>
            <weci:Employee_ID>11829</weci:Employee_ID>
        </weci:Worker_Summary>
        <weci:Effective_Change weci:Sequence="0">
            <weci:Derived_Event_Code>TER</weci:Derived_Event_Code>
            
        </weci:Effective_Change>
    </weci:Worker>
</weci:Workers_Effective_Stack>
<persons xmlns:ext="urn:calabriopersons">
    <person>
        <personid>00404e33-0c24-4846-b7db-b074006f4f25</personid>
        <wiserid>11829</wiserid>
    </person>
    <person>
        <personid>0043eeb1-1456-4ddf-b97c-b100009a79e9</personid>
        <wiserid>14119</wiserid>
    </person>

</persons>
</aggregate-data>

现有XSLT代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:wtdf="urn:com.workday/weci/tdf"
    xmlns:weci="urn:com.workday/weci"
    xmlns:ext="urn:calabriopersons"
    exclude-result-prefixes="xs"
    version="3.0">
    
    <xsl:mode streamable="yes" on-no-match="shallow-skip" use-accumulators="WorkerIDLookup CurrentLookupvalue"/>
    
    
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:accumulator name="CurrentLookupvalue" as="xs:string" initial-value="''" streamable="yes">
        <xsl:accumulator-rule match="ext:personid/text()" select="."/>
    </xsl:accumulator>
    
    <xsl:accumulator name="WorkerIDLookup" as="map(xs:string,xs:string)" initial-value="map{}" streamable="yes">
        <xsl:accumulator-rule match="ext:wiserid/text()" select="map:put($value, string(.), accumulator-before('CurrentLookupvalue'))"/>
    </xsl:accumulator>
    <xsl:accumulator name="weciWorker" as="xs:string" initial-value="''" streamable="yes">
        <xsl:accumulator-rule match="weci:Workers_Effective_Stack/weci:Worker/weci:Worker_Summary/weci:Employee_ID/text()" select="."/> 
    </xsl:accumulator>
    <xsl:template match="weci:Workers_Effective_Stack">
        
        <xsl:apply-templates
            select="copy-of(weci:Worker)[weci:Effective_Change/weci:Derived_Event_Code = 'HIR' or weci:Effective_Change/weci:Derived_Event_Code = 'TER']"
            mode="some-non-streamable-mode"/>
    </xsl:template> 
    
    <xsl:template match="weci:Worker"
        mode="some-non-streamable-mode">
        
        <xsl:for-each select="weci:Effective_Change[weci:Derived_Event_Code = 'TER']">
            
            <Set-Leaving-Date>
                
                {
                "PersonId": "<xsl:value-of select="accumulator-before('WorkerIDLookup')( accumulator-before('weciWorker') )"/>"
                 "Date": "2024-06-27"
                }
            </Set-Leaving-Date>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

预期输出

<?xml version="1.0" encoding="UTF-8"?>
<Set-Leaving-Date xmlns:ext="urn:calabriopersons"
              xmlns:map="http://www.w3.org/2005/xpath-functions/map"
              xmlns:weci="urn:com.workday/weci"
              xmlns:wtdf="urn:com.workday/weci/tdf">
            
            {
            "PersonId": "00404e33-0c24-4846-b7db-b074006f4f25"
             "Date": "2024-06-27"
            }
        </Set-Leaving-Date>

实际输出

<?xml version="1.0" encoding="UTF-8"?>
<Set-Leaving-Date xmlns:ext="urn:calabriopersons"
              xmlns:map="http://www.w3.org/2005/xpath-functions/map"
              xmlns:weci="urn:com.workday/weci"
              xmlns:wtdf="urn:com.workday/weci/tdf">
            
            {
            "PersonId": ""
             "Date": "2024-06-27"
            }
        </Set-Leaving-Date>

问题分析与修正方案

核心问题点

  1. 命名空间匹配错误:输入XML中的personid和wiserid元素无命名空间(仅persons元素声明了ext前缀,但未设置默认命名空间),原代码中使用ext:personid和ext:wiserid无法匹配到目标节点,导致Lookup map未正确构建。
  2. 累加器未启用:weciWorker累加器未添加到主模式的use-accumulators列表中,始终保持初始空值。
  3. 流处理顺序问题:输入中weci:Workers_Effective_Stack节点在前,处理该节点时,后续的persons节点尚未被处理,WorkerIDLookup的map仍为空,无法查到对应值。
  4. 累加器调用时机错误:使用accumulator-before获取Lookup map,此时map未完全构建完成,应使用accumulator-after确保所有数据已处理。

修正后的XSLT代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:wtdf="urn:com.workday/weci/tdf"
    xmlns:weci="urn:com.workday/weci"
    xmlns:ext="urn:calabriopersons"
    exclude-result-prefixes="xs"
    version="3.0">
    
    <!-- 启用所有需要的累加器 -->
    <xsl:mode streamable="yes" on-no-match="shallow-skip" use-accumulators="WorkerIDLookup CurrentLookupvalue weciWorker"/>
    
    <xsl:output method="xml" indent="yes"/>
    
    <!-- 匹配无命名空间的personid -->
    <xsl:accumulator name="CurrentLookupvalue" as="xs:string" initial-value="''" streamable="yes">
        <xsl:accumulator-rule match="personid/text()" select="."/>
    </xsl:accumulator>
    
    <!-- 匹配无命名空间的wiserid,构建Lookup映射 -->
    <xsl:accumulator name="WorkerIDLookup" as="map(xs:string,xs:string)" initial-value="map{}" streamable="yes">
        <xsl:accumulator-rule match="wiserid/text()" select="map:put($value, string(.), accumulator-before('CurrentLookupvalue'))"/>
    </xsl:accumulator>
    
    <xsl:accumulator name="weciWorker" as="xs:string" initial-value="''" streamable="yes">
        <xsl:accumulator-rule match="weci:Workers_Effective_Stack/weci:Worker/weci:Worker_Summary/weci:Employee_ID/text()" select="."/> 
    </xsl:accumulator>
    
    <!-- 先处理persons节点构建Lookup映射,再处理Worker数据 -->
    <xsl:template match="aggregate-data">
        <!-- 先遍历persons节点触发累加器构建映射 -->
        <xsl:apply-templates select="persons" mode="streamable"/>
        <!-- 再处理Worker数据 -->
        <xsl:apply-templates select="weci:Workers_Effective_Stack"/>
    </xsl:template>
    
    <xsl:template match="weci:Workers_Effective_Stack">
        <xsl:apply-templates
            select="copy-of(weci:Worker)[weci:Effective_Change/weci:Derived_Event_Code = 'HIR' or weci:Effective_Change/weci:Derived_Event_Code = 'TER']"
            mode="some-non-streamable-mode"/>
    </xsl:template> 
    
    <xsl:template match="weci:Worker" mode="some-non-streamable-mode">
        <xsl:for-each select="weci:Effective_Change[weci:Derived_Event_Code = 'TER']">
            <Set-Leaving-Date>
                {
                "PersonId": "<xsl:value-of select="accumulator-after('WorkerIDLookup')(weci:Worker_Summary/weci:Employee_ID)"/>"
                 "Date": "2024-06-27"
                }
            </Set-Leaving-Date>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

修正说明

  • 移除了personid和wiserid匹配路径中的ext:前缀,确保匹配到无命名空间的目标节点。
  • 将weciWorker添加到主模式的use-accumulators列表,启用该累加器。
  • 修改根节点模板,先处理persons节点构建Lookup映射,再处理weci:Workers_Effective_Stack,确保Lookup map已完全构建。
  • 在Lookup时直接从当前Worker节点获取Employee_ID值,替代依赖累加器的方式,避免累加器值被后续Worker覆盖的问题;同时使用accumulator-after获取完整构建的Lookup map。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 15:55:54