在XSLT中为XML字段添加计数器/序列号的问题求助
问题描述
尝试使用XSLT为/M_856/G_HL/S_HL段添加序列号:D_628字段需从1开始生成连续序列,D_734字段需从0开始生成对应序列。当前D_628能正常工作,但D_734无法按预期生成0开头的序列。
源XML
<M_856> <G_HL> <S_HL> <D_628></D_628> <D_734></D_734> <D_735>O</D_735> </S_HL> </G_HL> <G_HL> <S_HL> <D_628></D_628> <D_734></D_734> <D_735>T</D_735> </S_HL> </G_HL> <G_HL> <S_HL> <D_628></D_628> <D_734></D_734> <D_735>T</D_735> </S_HL> </G_HL> <G_HL> <S_HL> <D_628></D_628> <D_734></D_734> <D_735>I</D_735> </S_HL> </G_HL> <G_HL> <S_HL> <D_628></D_628> <D_734></D_734> <D_735>I</D_735> </S_HL> </G_HL> </M_856>
期望输出
<M_856> <G_HL> <S_HL> <D_628>1</D_628> <D_734>0</D_734> <D_735>O</D_735> </S_HL> </G_HL> <G_HL> <S_HL> <D_628>2</D_628> <D_734>1</D_734> <D_735>T</D_735> </S_HL> </G_HL> <G_HL> <S_HL> <D_628>3</D_628> <D_734>2</D_734> <D_735>T</D_735> </S_HL> </G_HL> <G_HL> <S_HL> <D_628>4</D_628> <D_734>3</D_734> <D_735>I</D_735> </S_HL> </G_HL> <G_HL> <S_HL> <D_628>5</D_628> <D_734>4</D_734> <D_735>I</D_735> </S_HL> </G_HL> </M_856>
当前使用的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="M_856/G_HL/S_HL/D_628"> <xsl:copy> <xsl:number count="M_856/G_HL/S_HL/D_628" start-at="1" level="any"/> </xsl:copy> </xsl:template> <xsl:template match="M_856/G_HL/S_HL/D_734"> <xsl:copy> <xsl:number count="M_856/G_HL/S_HL/D_734" start-at="0" level="any"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
问题原因与解决方案
原XSLT中,<xsl:number>的start-at属性仅定义序列的起始基准,但默认计数逻辑仍从1开始累加,因此无法直接生成0开头的序号。正确的做法是基于G_HL节点的位置来生成两个字段的序列:
D_628直接使用G_HL的位置序号(从1开始)D_734使用G_HL的位置序号减1(从0开始)
修正后的XSLT代码:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 复制所有未匹配的节点,保留原有结构 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 处理D_628:生成从1开始的序列 --> <xsl:template match="M_856/G_HL/S_HL/D_628"> <xsl:copy> <xsl:number count="M_856/G_HL" level="any"/> </xsl:copy> </xsl:template> <!-- 处理D_734:生成从0开始的序列 --> <xsl:template match="M_856/G_HL/S_HL/D_734"> <xsl:copy> <xsl:value-of select="count(preceding::M_856/G_HL)"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
代码说明
- 身份模板:
<xsl:template match="@*|node()">确保所有未被自定义模板匹配的节点和属性都被原样复制,保留XML的原始结构。 - D_628处理:通过
count="M_856/G_HL"统计当前节点对应的G_HL位置,生成从1开始的序号。 - D_734处理:使用
count(preceding::M_856/G_HL)统计当前G_HL节点之前的同层级节点数量,直接得到从0开始的序号。
这样处理后,就能精准生成符合要求的序列。
内容的提问来源于stack exchange,提问作者AnirD
相关产品推荐
相关产品推荐

