You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Saxon HE 9.7中xs:integer传变量编译报错,变量实为有效整数字符串

问题描述

使用Saxon SAXON-HE 9.7.0.15J执行以下XQuery脚本:

let $i := $input//*:i
let $code := substring($i,4,4)
let $n := xs:integer($code)

return $n

其中$input对应的XML为:

<req>
<i>1234004</i>
</req>

编译时出现错误**"Cannot convert zero-length string to an integer"**,但预期运行时$code应为"4004"。使用castable判断或number()函数的脚本可正常执行,疑问为何无法将变量传入xs:integer()。

原因分析

Saxon HE 9.7在编译阶段会执行静态类型检查:

  • $input//*:i返回的是元素节点序列,编译器无法在编译阶段确定该序列一定非空(比如XML中不存在<i>节点的情况)。
  • 当$i为空序列时,substring($i,4,4)会返回空字符串,而xs:integer()不允许传入空字符串作为参数。
  • 编译器预判到这种潜在错误场景,因此提前抛出编译错误。

而number()函数对空字符串会返回NaN,不会触发编译级别的限制;castable判断是在运行时进行类型校验,也不会在编译阶段报错。

解决方法

可以通过以下几种方式解决这个问题:

  • 明确获取非空文本节点:将$i的定义改为获取单个文本节点,确保静态分析时确定其非空(假设XML结构固定):
    let $i := $input//*:i/text()[1]
    let $code := substring($i,4,4)
    let $n := xs:integer($code)
    
    return $n
    
  • 添加运行时类型检查:用castable判断确保转换安全:
    let $i := $input//*:i
    let $code := substring($i,4,4)
    let $n := if ($code castable as xs:integer) then xs:integer($code) else ()
    
    return $n
    
  • 使用number()函数替代:注意number()对非数字字符串会返回NaN,需后续处理:
    let $i := $input//*:i
    let $code := substring($i,4,4)
    let $n := number($code)
    
    return $n
    
  • 添加节点存在性检查:先确保$i非空再执行转换:
    let $i := $input//*:i
    let $n := if (exists($i)) then xs:integer(substring($i,4,4)) else ()
    
    return $n
    

内容的提问来源于stack exchange,提问作者Vladimir Dyuzhev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 16:52:43