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

XSLT 3.0实现按occurrences值复制XML记录并添加自增ID

XSLT 3.0 实现按指定次数复制记录并生成连续自增ID

直接用XSLT 3.0的序列映射特性就能实现,不需要递归或者复杂的计数逻辑,完整代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xs">

  <xsl:template match="breakfast_menu">
    <xsl:copy>
      <xsl:for-each select="food ! (
        let $current-food := .,
            $repeat-times := xs:integer($current-food/occurrences)
        return for $i in 1 to $repeat-times return $current-food
      )">
        <xsl:copy>
          <!-- 插入连续自增ID -->
          <id><xsl:value-of select="position()"/></id>
          <!-- 复制原记录全部子节点 -->
          <xsl:copy-of select="child::node()"/>
        </xsl:copy>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

关键实现说明

  • 复制逻辑:用XSLT 3.0的映射运算符!遍历每个food节点,读取occurrences转为整数后,生成对应长度的节点序列——occurrences值是几,序列里就包含几个当前food节点,自动完成复制,不需要手写递归循环。
  • 自增ID:xsl:for-each遍历的是所有复制完成后的完整节点序列,直接调用内置函数position()就能拿到从1开始的连续序号,不需要额外维护计数变量,也能保证ID不会断号。
  • 兼容性:这段代码直接复制原节点下的所有子元素,后续原XML结构新增字段时不需要修改XSLT逻辑,自动适配。

如果偏好更精简的写法,也可以把循环部分简化成:

<xsl:for-each select="food ! (xs:integer(occurrences) => (1 to .) ! ../)">

运行效果完全一致,只是可读性稍差。

用提供的示例XML运行这段代码,输出结果和预期结果完全匹配:occurrences为1的 Belgian Waffles 仅输出1次,occurrences为2的Strawberry Belgian Waffles输出2次,ID从1到3连续递增。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 02:15:38