XSLT2.0模板调用local:add-business-days函数报错:找不到匹配单参数函数
XSLT2.0 函数找不到错误的原因与修复
错误根源:函数定义位置不符合规范
XSLT2.0 明确规定,<xsl:function>必须是<xsl:stylesheet>的直接子节点(顶层元素),不能嵌套在<xsl:template>内部。你把local:add-business-days放在add-period模板里,处理器根本识别不到这个函数,所以会抛出“找不到匹配函数”的错误。
隐藏问题:原逻辑未实现核心需求
除了定义位置错误,你的代码逻辑也完全偏离需求——原写法只是一直加日期直到超过$new-date,不管是不是周末都推进日期,等于没排除周末,而且$period参数完全没用来计数需要添加的工作日,纯属摆设。
修正后的完整代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:local="http://example.com/local"> <!-- 自定义函数必须放在顶层,作为stylesheet的直接子节点 --> <xsl:function name="local:add-business-days" as="xs:date"> <xsl:param name="start-date" as="xs:date"/> <xsl:param name="days-to-add" as="xs:integer"/> <xsl:param name="workdays" as="xs:string*"/> <xsl:choose> <!-- 剩余工作日加完了,返回当前日期 --> <xsl:when test="$days-to-add = 0"> <xsl:sequence select="$start-date"/> </xsl:when> <!-- 当天是工作日,加1天并减少剩余要加的天数 --> <xsl:when test="index-of($workdays, format-date($start-date, '[FNn]'))"> <xsl:sequence select="local:add-business-days($start-date + xs:dayTimeDuration('P1D'), $days-to-add - 1, $workdays)"/> </xsl:when> <!-- 当天是周末,只推进日期,剩余天数不变 --> <xsl:otherwise> <xsl:sequence select="local:add-business-days($start-date + xs:dayTimeDuration('P1D'), $days-to-add, $workdays)"/> </xsl:otherwise> </xsl:choose> </xsl:function> <xsl:template name="add-period" as="xs:date"> <xsl:param name="date" as="xs:date"/> <xsl:param name="period" as="xs:dayTimeDuration"/> <!-- 把时长转换为整数天数 --> <xsl:variable name="total-days" select="xs:integer($period div xs:dayTimeDuration('P1D'))"/> <xsl:variable name="workdays" select="tokenize('Monday,Tuesday,Wednesday,Thursday,Friday', ',')"/> <xsl:sequence select="local:add-business-days($date, $total-days, $workdays)"/> </xsl:template> </xsl:stylesheet>
关键修改点
- 把
local:add-business-days移到<xsl:stylesheet>直接子节点位置,让处理器能正确识别 - 给函数新增
days-to-add参数,用来计数需要添加的工作日数量,真正实现“排除周末加天数”的逻辑 - 将
workdays作为参数传入函数,避免依赖外部变量,函数独立性更强 - 修复原代码中
$period参数未被有效利用的问题,先把时长转成整数天数再处理
内容的提问来源于stack exchange,提问作者Brca
相关产品推荐
相关产品推荐

