XSLT多invoiceLine场景下substring-after函数报错排查
错误原因
- 节点名匹配错误:源XML的行节点名为驼峰格式
invoiceLine,原代码模板匹配写的是全小写/invoiceline,无法正确匹配到目标节点,导致key查找脱离了单条发票行的上下文。 - 全局key跨节点返回多值:
xsl:key默认是全局索引,当存在多条invoiceLine时,调用key('note', 折扣编码)会把所有行里匹配该编码的Note节点全部返回(比如编码003会同时返回第一行的11_003_CCC、第二行的21_003_CCC两个节点),而substring-after()函数要求第一个入参必须是单个字符串值,传入多节点序列直接触发致命错误。 - 格式逻辑缺陷:原代码的数字格式化规则带千分位分隔符,输出的折扣率格式不符合预期,也没有按要求添加换行和
<br />标签。
修正后的可运行XSLT代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="2.0" encoding="UTF-8" omit-xml-declaration="yes"/> <!-- 定义折扣编码匹配key --> <xsl:key name="note" match="Note" use="substring-before(substring-after(., '_'), '_')" /> <xsl:template match="/"> <xsl:for-each select="//invoiceLine"> <!-- 暂存当前发票行节点,作为key查找的上下文边界 --> <xsl:variable name="currentLine" select="."/> <xsl:for-each select="$currentLine/AllowanceCharge/MultiplierFactorNumeric"> <xsl:text>%</xsl:text> <!-- 修正格式化规则,输出X,00格式的折扣率 --> <xsl:value-of select="format-number(. * 100, '0,00', 'european')"/> <xsl:text> </xsl:text> <!-- 传入第三个参数限定key仅在当前发票行内查找,避免返回跨节点多值 --> <xsl:value-of select="substring-after(substring-after(key('note', format-number(100 * ., '000'), $currentLine), '_'), '_')"/> <!-- 非行尾条目追加<br />标签 --> <xsl:if test="not(position() = last())"> <xsl:text> <br /></xsl:text> </xsl:if> <xsl:text> </xsl:text> </xsl:for-each> </xsl:for-each> </xsl:template> </xsl:stylesheet>
输出验证
传入提供的源XML运行上述代码,将完全匹配预期输出:
%3,00 CCC <br /> %5,00 AAA %3,00 CCC <br /> %2,00 BBB
内容的提问来源于stack exchange,提问作者Fatih Aydin
相关产品推荐
相关产品推荐

