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

XSLT3.0累加器使用问题:替换<SAL>节点值失败求助

问题:用XSLT 3.0累加器替换节点值

数据源

数据源1

<Reference>
  <Worker>
    <Employee_ID>1234</Employee_ID>
    <Salary_Type>H</Salary_Type>
  </Worker>
  <Worker>
    <Employee_ID>5678</Employee_ID>
    <Salary_Type>H</Salary_Type>
  </Worker>
</Reference>

数据源2

<root>
  <row>
     <ID>1234</ID>
     <ADDR>ABC</ADDR>
     <PHONE>9999999998</PHONE>            
     <SAL>S</SAL>          
  </row>
  <row>
    <ID>5678</ID>
    <ADDR>ABD</ADDR>
    <PHONE>9999999999</PHONE>  
    <SAL>S</SAL>
  </row>
</root>

合并后的XML结构

<root>
  <Reference>
    <Worker>
      <EmployeeID>1234</Employee_ID>
      <SalaryType>H</Salary_Type>
    </Worker>
    <Worker>
      <EmployeeID>5678</Employee_ID>
      <SalaryType>H</Salary_Type>
    </Worker>
  </Reference>
  <root>
    <row>
      <ID>1234</ID>
      <ADDR>ABC</ADDR>
      <PHONE>9999999998</PHONE>            
      <SAL>S</SAL>          
    </row>
    <row>
      <ID>5678</ID>
      <ADDR>ABD</ADDR>
      <PHONE>9999999999</PHONE>  
      <SAL>S</SAL>
    </row>
  </root>
</root>

尝试的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" exclude-result-prefixes="#all" version="3.0">
   <xsl:mode streamable="no" on-no-match="shallow-copy" use-accumulators="#all"/>
   <xsl:output method="xml" indent="yes"/>
   <xsl:strip-space elements="*"/>
   <xsl:accumulator name="EIDKey" as="xs:string" initial-value="''" streamable="yes">
      <xsl:accumulator-rule match="/root/Reference/Worker/EmployeeID/text()" select="."/> 
   </xsl:accumulator>
   <xsl:accumulator name="PayTypeLookup" as="map(xs:string,xs:string)" initial-value="map {}"     
      streamable="yes">
      <xsl:accumulator-rule match="/root/Reference/Worker/SalaryType/text()"  
         select="map:put($value, accumulator-before('EIDKey'), string(.))"/>
   </xsl:accumulator>
   <xsl:template match="/">
      <root>
         <xsl:for-each select="root/root/row"> 
            <row>
               <xsl:apply-templates/>
            </row>
         </xsl:for-each>
      </root>
   </xsl:template>
   
   <xsl:template match="SAL">
      <xsl:variable name="PayType" select="normalize-space(.)"/>
      <SAL><xsl:value-of select="accumulator-before('PayTypeLookup')($PayType)"/></SAL> 
   </xsl:template>
</xsl:stylesheet>

期望输出

<root>
  <row>
    <ID>1234</ID>
    <ADDR>ABC</ADDR>
    <PHONE>9999999998</PHONE>            
    <SAL>H</SAL>          
  </row>
  <row>
    <ID>5678</ID>
    <ADDR>ABD</ADDR>
    <PHONE>9999999999</PHONE>  
    <SAL>H</SAL>
  </row>
</root>

问题分析与修正方案

核心问题点

  1. 标签匹配错误:合并后的XML中<EmployeeID>与结束标签<Employee_ID>不统一,<SalaryType>与结束标签<Salary_Type>不统一,导致累加器无法捕获节点值。
  2. 映射逻辑错误:用<SAL>的旧值作为键查找映射,实际应该用<row>下的<ID>值作为键,关联对应的薪资类型。
  3. 累加器触发顺序不可靠:依赖文本节点的匹配顺序构建映射,容易出现键值不对应的问题。

修正后的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"
    exclude-result-prefixes="#all"
    version="3.0">

    <xsl:mode on-no-match="shallow-copy" use-accumulators="payTypeMap"/>
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <!-- 构建员工ID到薪资类型的映射 -->
    <xsl:accumulator name="payTypeMap" as="map(xs:string, xs:string)" initial-value="map{}">
        <xsl:accumulator-rule match="/root/Reference/Worker" 
            select="map:put($value, string(EmployeeID), string(SalaryType))"/>
    </xsl:accumulator>

    <!-- 输出目标根结构 -->
    <xsl:template match="/">
        <root>
            <xsl:apply-templates select="/root/root/row"/>
        </root>
    </xsl:template>

    <!-- 替换SAL节点值 -->
    <xsl:template match="SAL">
        <SAL>
            <xsl:value-of select="accumulator-before('payTypeMap')(string(../ID))"/>
        </SAL>
    </xsl:template>

</xsl:stylesheet>

修正说明

  1. 修复标签匹配:确保累加器匹配的节点标签与合并后的XML一致。
  2. 优化映射构建:直接在<Worker>节点级别构建映射,将EmployeeID作为键、SalaryType作为值,避免依赖文本节点的匹配顺序。
  3. 修正查找逻辑:处理<SAL>时,使用当前<row>的<ID>值作为键,从累加器映射中获取对应的薪资类型值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 17:20:26