XSLT1.0转换XML时生成唯一CASH_RECEIPT_LINE_NO的方法
问题原因
你遇到的编号重复问题,根源是position()函数取的是当前SalgsKampanje节点在集合中的位置,每遍历1个SalgsKampanje节点最多生成2个行记录,但position()只会随着SalgsKampanje的遍历递增加1,因此第二个及以后的SalgsKampanje生成的行编号会和前一个的重叠。
解决方案1:简单偏移修正(允许跳号场景)
如果业务允许跳过未满足if条件的行号,直接调整偏移量即可,每个SalgsKampanje预留2个编号位,修改两处行号生成逻辑:
- DISCOUNT类型行的行号
<CASH_RECEIPT_LINE_NO> <!-- 每个SalgsKampanje占2个号位,第一行加1 --> <xsl:value-of select="(position() - 1)*2 + 5001"/> </CASH_RECEIPT_LINE_NO>
- VATRET类型行的行号
<CASH_RECEIPT_LINE_NO> <!-- 每个SalgsKampanje占2个号位,第二行加2 --> <xsl:value-of select="(position() - 1)*2 + 5002"/> </CASH_RECEIPT_LINE_NO>
修改后不管有多少条SalgsKampanje记录,都不会出现编号重复。
解决方案2:预生成节点遍历(严格连续无跳号场景)
如果要求实际输出的行号完全连续无跳号,可先把所有满足条件的行预存为节点集,再统一遍历生成编号(XSLT1.0需要借助EXSLT的node-set扩展):
- 首先在
xsl:stylesheet根节点新增扩展声明:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns3="http://NEXSTEP.Schemas.Bonger" xmlns:ns2="http://NEXSTEP.Schemas.NexstepTypes" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="ns2 ns3 exsl">
- 把原
<LINES>节点内的逻辑替换为以下代码:
<LINES> <!-- 预存所有符合条件的行参数 --> <xsl:variable name="lineParams"> <xsl:for-each select="MESSAGE_RECORD/InsertChange/SalgsKampanjer/SalgsKampanje"> <xsl:if test="KampanjeSumInkVat > 0"> <line type="DISCOUNT" kampanje="current()"/> </xsl:if> <xsl:variable name="variant" select="-translate(translate(KampanjeSumInkVat,'-','') - translate(KampanjeSumEksVat,'-',''),'-','')"/> <xsl:if test="$variant != 0"> <line type="VATRET" kampanje="current()" variant="{$variant}"/> </xsl:if> </xsl:for-each> </xsl:variable> <xsl:variable name="validLines" select="exsl:node-set($lineParams)/line"/> <!-- 统一遍历生成连续编号 --> <xsl:for-each select="$validLines"> <xsl:variable name="k" select="@kampanje"/> <CASH_RECEIPT_LINE> <CASH_RECEIPT_LINE_NO> <xsl:value-of select="position() + 5000"/> </CASH_RECEIPT_LINE_NO> <xsl:choose> <xsl:when test="@type='DISCOUNT'"> <INTERNAL_TRANSACTION_CODE>DISCOUNT</INTERNAL_TRANSACTION_CODE> <EXTERNAL_TRANSACTION_CODE> <xsl:value-of select="$k/KampanjeKode"/> </EXTERNAL_TRANSACTION_CODE> <REFERENCE/> <ACTUAL_AMOUNT> <xsl:value-of select="$k/KampanjeSumEksVat"/> </ACTUAL_AMOUNT> <QUANTITY>1</QUANTITY> <TOTAL_AMOUNT> <xsl:value-of select="$k/KampanjeSumEksVat"/> </TOTAL_AMOUNT> <CURRENCY_CODE> <xsl:value-of select="$k/../../totalSum/ns2:Valutakode"/> </CURRENCY_CODE> <FREE_TEXT_1> <xsl:value-of select="$k/KampanjeBeskrivelse"/> </FREE_TEXT_1> </xsl:when> <xsl:when test="@type='VATRET'"> <INTERNAL_TRANSACTION_CODE>VATRET</INTERNAL_TRANSACTION_CODE> <EXTERNAL_TRANSACTION_CODE> <xsl:value-of select="$k/KampanjaMvaKode"/> </EXTERNAL_TRANSACTION_CODE> <ACTUAL_AMOUNT> <xsl:value-of select="@variant"/> </ACTUAL_AMOUNT> <QUANTITY>0</QUANTITY> <TOTAL_AMOUNT> <xsl:value-of select="@variant"/> </TOTAL_AMOUNT> <CURRENCY_CODE> <xsl:value-of select="$k/../../totalSum/ns2:Valutakode"/> </CURRENCY_CODE> </xsl:when> </xsl:choose> </CASH_RECEIPT_LINE> </xsl:for-each> </LINES>
该方案可以保证最终输出的所有行编号完全连续,不会出现跳号、重复问题。
内容的提问来源于stack exchange,提问作者Shanka Somasiri
相关产品推荐
相关产品推荐

