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:
<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>
- 修改原有的
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
相关产品推荐
相关产品推荐

