PhoenixmlDb.XQuery
XdmShape
The one place that states how an XDM sequence and an XDM array are told apart at runtime, and the safe operations over that distinction.
#XdmShape
Namespace: PhoenixmlDb.XQuery
The one place that states how an XDM
sequence
and an XDM
array
are told apart at runtime, and the safe operations over that distinction.
The convention: a SEQUENCE is object?[], an ARRAY is List<object?>, and a single item is itself. Nothing in the type system says so — both are just containers of object?, they have the same shape, and the compiler cannot help. Every consumer has to remember, and five did not:
-
the
xqueryCLI's serializer printed12for[1,2] -
SerializeItemAdaptivegave sequences array brackets -
the QT3 runner flattened arrays when binding
$result— 56 failures -
xsl:array's spread would have flattened a nested array member -
xsl:arrayhanded the finished array on AS a sequence
The last is the one to learn from. It produced the RIGHT answer for the obvious case — <xsl:array select="1 to 5"/> still printed [1,2,3,4,5] — and broke only at the edges, where a one-member array collapsed to its member and composite="yes" silently became a no-op. A fix verified against the reported case alone would have shipped looking complete.
This is mitigation, not the fix. The fix is a wrapper type so the compiler enforces the distinction; that is a refactor of ~90 sites across two shipping engines and has not been done. What this class does is give the three decisions that actually went wrong — "is this one item or many?", "what do I iterate?", "how do I hand this on?" — names that say which answer you are asking for.
#Methods
#ArrayMembers(Object)
The members of
when it is an array;
null
when it is not.
Use when you mean "look inside this array", never to iterate a sequence.
#AsArray(Collections.Generic.IEnumerable<Object>)
Packages
as an ARRAY value — always one item, never unwrapped.
The counterpart to
, and the operation
xsl:array
got wrong by calling
.ToArray()
: that produced a sequence of the members instead of an array.
#AsSequence(Collections.Generic.IReadOnlyList<Object>)
Packages
as a SEQUENCE value: empty stays empty, one item unwraps to itself, and more become
object?[]
.
The unwrap matters: a one-item sequence IS its item in XDM, and leaving it wrapped makes downstream shape tests disagree with the spec.
#IsArray(Object)
True if the value is an XDM array. An array is ONE item.
#IsSequence(Object)
True if the value is a multi-item sequence representation.
#Render(Object)
The XQuery type name of a VALUE — "xs:integer", "xs:byte", "map(*)" — for diagnostics and for
fn:type
.
Renders a value for human display, as
fn:trace
and other diagnostics need.
Exists because CLR class names were leaking into user-visible text. Two symptoms, one cause:
fn:type(xs:byte(1))
reported
"XsTypedInteger"
, and type errors read "but got Int64". Both are the runtime describing its own implementation to someone who wrote XQuery and can only act on XQuery type names. Derived values carry their subtype in a TypeName tag (XsTypedInteger / XsTypedString), so xs:byte(1) reports "xs:byte" while an untagged 1 reports "xs:integer" — which is the correct XDM answer, not an approximation: an untagged integer's dynamic type IS xs:integer and never a proper subtype of it.
Interpolating a value directly gives the CLR type name for anything held in a container: a sequence prints as System.Object[] and an array as System.Collections.Generic.List`1[System.Object]. That is useless in a diagnostic and actively defeats fn:trace, whose entire purpose is letting someone look at a value.
Lives here, beside XdmShape.TypeOf, because this is the third caller to need the shape vocabulary and the first two were only unified after they had already drifted. Rendering is deliberately approximate rather than a serialization: it exists to be read, not parsed, and must never throw or run long on a pathological value.
#SequenceItems(Object)
The items of
viewed as a SEQUENCE: a sequence yields its items, and everything else — including an array — is a single item.
Use when iterating "the things in this value". An array must NOT be spread here: it is one item whose members are its own business.
#TypeNameOf(Object)
The XQuery type name of a value. See
.