升级XSLT至3.0后xsl:when内string-length报XPTY0004错误
问题根因
XSLT 1.1基于XPath 1.0规范,对函数参数的类型校验非常宽松:当传入多节点序列作为单值函数的参数时,运行时会隐式提取序列第一个节点的字符串值参与计算,直接忽略序列中剩余的项,不会抛出错误。
XSLT 3.0基于XPath 3.0规范,执行严格的动态类型校验:fn:string-length()的入参明确要求为单字符串值(或可原子化为单字符串的0/1个节点),如果传入长度大于1的序列,会直接抛出XPTY0004类型错误。你遇到的报错信息里明确显示传入了两个项(空字符串、带连续空格的字符串),说明你写的XPath表达式实际匹配到了2个节点/值,在1.1版本中运行时隐式取了第一个项计算,到3.0版本因为类型校验不通过直接报错。
修复方案
根据实际要实现的业务逻辑,选择对应修改方式即可:
- 需要完全对齐XSLT 1.1的原有逻辑(仅判断第一个匹配项的字符串长度):给XPath表达式整体加括号后取第一个项,保证传入
string-length()的永远是单值,示例代码:<!-- 原有错误写法 --> <xsl:when test="string-length(//your/node/path)"> <!-- 修改后,和1.1行为完全一致 --> <xsl:when test="string-length( (//your/node/path)[1] )">注意必须给XPath整体加括号,否则位置谓词
[1]只会作用于路径的最后一步,无法保证取整个表达式返回结果的第一个项。 - 业务逻辑为判断匹配到的所有项中是否存在非空内容:用XPath 3.0的
some语义判断,避免漏判后续节点的内容,示例:<!-- 忽略全空格的无效内容,判断是否存在至少一个有效非空值 --> <xsl:when test="some $cur in //your/node/path satisfies string-length(normalize-space($cur)) gt 0"> - 业务逻辑为判断所有匹配项拼接后的总字符串长度:先用
string-join()把多值序列转为单字符串,再传入string-length()计算,示例:<xsl:when test="string-length(string-join(//your/node/path, ''))">
内容的提问来源于stack exchange,提问作者unknown_11
相关产品推荐
相关产品推荐

