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

如何在XSLT3.0中正确使用map:put()更新XML数据映射

XSLT 3.0 映射更新问题解决及实现方案

核心问题定位

你遇到的map:put()问题,根源在于XSLT 3.0中的map是不可变对象:map:put()不会修改原有映射,而是返回一个包含新键值对的全新映射。如果没有将这个新映射传递到后续处理逻辑中,就无法维护递增的计数状态。

需求实现方案

针对你的业务规则,我们可以用xsl:iterate(XSLT 3.0新增的状态迭代工具)结合不可变map来实现,步骤如下:

1. 预处理资产查找映射

先把Asset Information文件转换成键为Asset_Identifier、值为Location_ID的map,方便快速查询:

<xsl:variable name="asset-lookup-map" as="map(xs:string, xs:string)">
  <xsl:map>
    <xsl:for-each select="document('asset-information.xml')//Asset">
      <xsl:map-entry key="string(Asset_Identifier)" select="string(Location_ID)"/>
    </xsl:for-each>
  </xsl:map>
</xsl:variable>

2. 迭代处理Journal Lines并维护计数映射

用xsl:iterate逐条处理Journal Lines记录,每次迭代更新计数映射并传递到下一轮:

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:map="http://www.w3.org/2005/xpath-functions/map">
  <xsl:output method="xml" indent="yes"/>

  <xsl:variable name="asset-lookup-map" as="map(xs:string, xs:string)">
    <xsl:map>
      <xsl:for-each select="document('asset-information.xml')//Asset">
        <xsl:map-entry key="string(Asset_Identifier)" select="string(Location_ID)"/>
      </xsl:for-each>
    </xsl:map>
  </xsl:variable>

  <xsl:template match="/">
    <Output>
      <xsl:iterate select="document('journal-lines.xml')//JournalLine">
        <!-- 初始状态:空计数映射 -->
        <xsl:param name="counter-map" as="map(xs:string, xs:integer)" select="map{}"/>

        <xsl:variable name="current-asset-id" select="string(Asset_Identifier)"/>
        <!-- 获取当前计数,不存在则返回空序列 -->
        <xsl:variable name="current-count" select="$counter-map($current-asset-id, ())"/>
        
        <!-- 计算新的Asset_Identifier_Extension值 -->
        <xsl:variable name="new-extension" as="xs:integer">
          <xsl:choose>
            <xsl:when test="empty($current-count)">
              <!-- 首次处理:存在资产信息则设为1,否则设为0 -->
              <xsl:choose>
                <xsl:when test="exists($asset-lookup-map($current-asset-id))">1</xsl:when>
                <xsl:otherwise>0</xsl:otherwise>
              </xsl:choose>
            </xsl:when>
            <xsl:otherwise>
              <!-- 后续处理:在当前计数基础上加1 -->
              <xsl:value-of select="$current-count + 1"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>

        <!-- 获取Location_ID,不存在则返回空字符串 -->
        <xsl:variable name="location-id" select="$asset-lookup-map($current-asset-id, '')"/>

        <!-- 生成输出记录 -->
        <JournalLine>
          <Asset_Identifier><xsl:value-of select="$current-asset-id"/></Asset_Identifier>
          <Asset_Identifier_Extension><xsl:value-of select="$new-extension"/></Asset_Identifier_Extension>
          <xsl:if test="$location-id ne ''">
            <Location_ID><xsl:value-of select="$location-id"/></Location_ID>
          </xsl:if>
          <!-- 保留原记录的其他字段 -->
          <xsl:copy-of select="* except Asset_Identifier"/>
        </JournalLine>

        <!-- 更新计数映射,传递到下一次迭代 -->
        <xsl:next-iteration>
          <xsl:with-param name="counter-map" select="map:put($counter-map, $current-asset-id, $new-extension)"/>
        </xsl:next-iteration>
      </xsl:iterate>
    </Output>
  </xsl:template>
</xsl:stylesheet>

关键细节说明

  • 不可变map的正确使用:每次调用map:put()后,必须将返回的新映射通过xsl:next-iteration传递给下一轮迭代,否则计数状态无法保留。
  • 状态维护:xsl:iterate是XSLT 3.0中处理逐次状态更新的最优方式,比递归调用更简洁易读。
  • 默认值处理:使用map($key, 默认值)语法处理键不存在的场景,避免空指针错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 14:24:50