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

XSLT 2.0中<xsl:number level="any"/>生成顺序计数器报错求解

问题原因

<xsl:number level="any"/>的设计逻辑是统计源输入XML文档中符合规则的节点的位置序号,你当前是在xsl:for-each遍历整数序列、动态生成新输出节点的场景下使用它,此时没有对应的源文档节点作为计数依据,部分XSLT 2.0处理器会直接抛出内部错误。

可行实现方案

用XSLT 2.0支持的**隧道参数(tunnel parameter)**实现全局连续计数,不需要在每一层模板调用时手动传参,不管ORDER_NOTE_SEG在转换流程的哪个位置生成,都能保证计数连续,最后用format-number直接输出4位补零的格式。

  1. 在你转换的入口模板(通常是匹配根节点/的模板)里初始化全局计数器,设为隧道参数,初始值为1:
<xsl:template match="/">
  <!-- 初始化全局NOTE行号计数器,隧道参数会自动在调用链传递,无需逐层手动声明 -->
  <xsl:param name="globalNoteCounter" as="xs:integer" select="1" tunnel="yes"/>
  <!-- 此处保留你原有的根节点输出逻辑,比如生成<ORDER_INB_IFD>等外层结构 -->
  <ORDER_INB_IFD>
    <CTRL_SEG>
      <ORDER_SEG>
        <!-- 原有业务逻辑、调用OrderNoteSeg模板的代码不需要修改 -->
      </ORDER_SEG>
    </CTRL_SEG>
  </ORDER_INB_IFD>
</xsl:template>
  1. 修改原有的OrderNoteSeg命名模板,接收隧道参数,循环生成分段时直接计算当前序号、格式化输出,最后把累加后的计数器继续通过隧道参数向外传递:
<xsl:template name="OrderNoteSeg">
    <xsl:param name="orderNumber"/>
    <xsl:param name="type"/>
    <xsl:param name="text"/>
    <!-- 接收全局计数隧道参数 -->
    <xsl:param name="globalNoteCounter" as="xs:integer" tunnel="yes"/>

    <!-- 计算当前文本需要拆分成多少个NOTE段 -->
    <xsl:variable name="segTotal" select="(string-length($text) - 1) idiv 60 + 1"/>
    <xsl:for-each select="0 to $segTotal - 1">
      <xsl:variable name="currentLineNo" select="$globalNoteCounter + position() - 1"/>
      <ORDER_NOTE_SEG>
        <SEGNAM>ORDER_NOTE</SEGNAM>
        <ORDNUM>
          <xsl:value-of select="$orderNumber"/>
        </ORDNUM>
        <NOTLIN>
          <!-- 直接格式化为4位数字,不足位前补0 -->
          <xsl:value-of select="format-number($currentLineNo, '0000')"/>
        </NOTLIN>
        <NOTTXT>
          <xsl:value-of select="substring($text, . * 60 + 1, 60)" />
        </NOTTXT>
        <NOTTYP>
          <xsl:value-of select="$type"/>
        </NOTTYP>
      </ORDER_NOTE_SEG>
    </xsl:for-each>

    <!-- 累加计数器,供后续生成的NOTE段继续使用 -->
    <xsl:apply-templates select="$globalNoteCounter + $segTotal" mode="update-note-counter"/>
</xsl:template>

<!-- 辅助模板:更新全局计数器值,不需要修改 -->
<xsl:template match="xs:integer" mode="update-note-counter">
  <xsl:param name="globalNoteCounter" as="xs:integer" tunnel="yes" select="."/>
</xsl:template>

说明:这个方案完全不依赖源文档节点结构,不管你在转换的哪个位置调用OrderNoteSeg模板,计数器都会全局连续递增,不会出现断号、重置的问题,输出的NOTLIN值固定为4位补零格式,和你给出的示例要求完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:42:37