为什么数字文字在 XQuery 中永远不能是 xs:positiveInteger 类型?

lin*_*e-o 3 xquery xquery-3.1

我注意到 XQuery 实现如何处理(子)类型的细微差别。特别是,将文字数字处理为声明了可接受输入类型的函数的输入。我天真地认为任何可转换为该特定数字类型的数字文字都会被接受。

declare function local:any ($n as xs:anyAtomic) { $n };
declare function local:decimal ($n as xs:decimal) { $n };
declare function local:integer ($n as xs:integer) { $n };
declare function local:pos-int ($n as xs:positiveInteger) { $n };

local:any(1), (: works :)
local:decimal(1), (: works :)
local:integer(1), (: works :)
local:pos-int(1)  (: throws in all tested implementations :)
Run Code Online (Sandbox Code Playgroud)

exist-db 允许xs:long, xs:int, ... Saxon 不允许。

我在 Xquery Spec 2.5.5 SequenceType Matching 和 Xpath 函数规范1.6.3 Atomic Type Hierarchy 中都找不到这种行为的任何原因

这里有人能解释一下为什么 Saxon 9.3.1 HE、BaseX 9.3.1 [Standalone] 和 eXist 5.3.0-SNAPSHOT 表现得像这样吗?

我是否只是错过了规范中定义将文字转换1为 xs:integer 的部分?xs:decimal 作为最顶层的类型会更有意义,但如果允许一个子类型,为什么不一路走呢?

这是一个现场演示

Mic*_*Kay 6

我认为这个领域的规范非常不幸,但很明显:一个值xs:positiveInteger只有在被标记时才是 an ,而不仅仅是因为它是 (a) 一个整数和 (b) 正数。XQuery 工作组对此进行了长时间的讨论,涉及一些编程语言类型系统方面的杰出专家(如 Phil Wadler),这就是做出的决定。我自己不喜欢。

规范在哪里说这个?XDM 规范中的定义是一个好的开始:

https://www.w3.org/TR/xpath-datamodel-31/#xs-types

[定义:原子值是原子类型值空间中的值,并用该原子类型的名称进行标记。]

[定义:原子类型是原始简单类型或通过限制从另一个原子类型派生的类型。](由列表或联合派生的类型不是原子的。)

[定义:原始简单类型是在 2.1.1 Types 采用的 XML Schema 中定义的类型。]

然后 XQuery 规范中的 §3.1.1 谈到了数字文字:

不包含“.”的数字文字的值。并且没有 e 或 E 字符是 xs:integer 类型的原子值。

§3.18.1 给出了“instance of”运算符的规则:

instance of根据 SequenceType 匹配规则,如果布尔运算符的第一个操作数的值与其第二个操作数中的 SequenceType 匹配,则布尔运算符返回 true;

和 §2.5.5.2 给出了 SequenceType 匹配的相关规则:

仅由 EQName 组成的 ItemType 被解释为 AtomicOrUnionType。如果派生-from( AT, AtomicOrUnionType ) 为真,则预期类型 AtomicOrUnionType 匹配实际类型为 AT 的原子值。

综合起来,结果是表达式3 instance of xs:positiveInteger返回 false(因为xs:integer不是从 派生的xs:positiveinteger)。

最后,当函数参数的预期类型是xs:positiveInteger,并且函数调用提供值 3 时,第 3.1.5.2 节中的函数转换规则就起作用了。这些允许从提供的值到所需类型的各种转换,但从 xs:integer 到 xs:positiveInteger 的“向下转换”不是其中之一。所以这是一个错误:

如果在上述转换之后,根据 SequenceType 匹配规则,结果值与预期类型不匹配,则会引发类型错误 [err:XPTY0004]。

正如我所说,我不喜欢这些规则,并曾多次尝试改变它们。但它们是明确的,任何不遵循它们的产品都是不合格的。