I think the spec in this area is very unfortunate, but it is clear: a value is an xs:positiveInteger
only if it is labelled as such, not simply because it is (a) an integer and (b) positive. There were long discussions about this in the XQuery Working Group, involving some eminent experts on programming language type systems (like Phil Wadler), and that's the decision that was made. I didn't like it myself.
Where does the spec say this? The definitions in the XDM spec are a good start:
https://www.w3.org/TR/xpath-datamodel-31/#xs-types
[Definition: An atomic value is a value in the value space of an
atomic type and is labeled with the name of that atomic type.]
[Definition: An atomic type is a primitive simple type or a type
derived by restriction from another atomic type.] (Types derived by
list or union are not atomic.)
[Definition: The primitive simple types are the types defined in 2.1.1
Types adopted from XML Schema.]
Then §3.1.1 in the XQuery spec talks about numeric literals:
The value of a numeric literal containing no "." and no e or E
character is an atomic value of type xs:integer.
§3.18.1 gives the rules for the "instance of" operator:
The boolean operator instance of
returns true if the value of its
first operand matches the SequenceType in its second operand,
according to the rules for SequenceType matching;
and §2.5.5.2 gives the relevant rule for SequenceType matching:
An ItemType consisting simply of an EQName is interpreted as an
AtomicOrUnionType. The expected type AtomicOrUnionType matches an
atomic value whose actual type is AT if derives-from( AT,
AtomicOrUnionType ) is true.
Taken together, the effect is that the expression 3 instance of xs:positiveInteger
returns false (because xs:integer
is not derived from xs:positiveinteger
).
Finally, when the expected type of a function argument is xs:positiveInteger
, and the function call supplies the value 3, then the function conversion rules in §3.1.5.2 come into play. These allow various conversions from the supplied value to the required type, but "down-casting" from xs:integer to xs:positiveInteger is not one of them. So it's an error:
If, after the above conversions, the resulting value does not match
the expected type according to the rules for SequenceType Matching, a
type error is raised [err:XPTY0004].
As I say, I don't like the rules and have tried on numerous occasions to get them changed. But they are clear, and any product that doesn't follow them is non-conformant.