instanceof
, the C++ dynamic_cast
, the Perl
isa
all provide for type identification, where
the reference type is named statically and must be known at compile time.
XQuery instance of
keyword pair.
instance of
, cast as
,
treat as
, and (in XQuery 3.0) validate as
constructs, and through the use of sequence type matching in
typeswitch
and argument or variable binding constructs. A program
can use the constructs to ensure that data is properly typed in accordance with
the assumptions of processing and dispatch to the appropriate processing for
the type. typeswitch
or instance of
test could be used to
determine which analysis function to apply, and type sequence matching could be
used to ensure that the analysis code is applied properly to ensure
correctness. In other cases castable as
and cast as
can be used to perform this job.
Class
class and the reflection API
/root/child/sc:simple-type()
possible.
sc
which the examples assume to be predefined. The specific namespace chosen is
not important. The experimental implementation used
http://marklogic.com/xdmp/schema-components
.
xs:untyped
and xs:untypedAtomic
represent such
untyped complex and simple content.
sc:simple-type
linkage function returns that simple type as a
component value. If the atomic type is untyped, then a simple type definition value
for xs:untypedAtomic
is returned. The accessor
sc:simple-type
operates on attribute nodes in a similar fashion.
The operation on element nodes is similar, except that if
the element is an instance of a complex type, sc:simple-type
returns the empty sequence. For other kinds of items, the empty sequence is returned.
sc:complex-type
works analogously
like sc:simple-type
except atomic values and attributes can never
be instances of a complex type, so sc:complex-type
is only useful
for element nodes. If an element node is an instance of a specific
complex type, the value will be that complex type as a component value. If the
element node is untyped, xs:untyped
will be returned as a complex type
component value. When an element is an instance of a simple type,
sc:complex-type
returns xs:anyType
as a complex type component
value. For other items, the empty sequence is returned.
sc:type
accessor combines certain aspects of the
sc:simple-type
and sc:complex-type
accessors. It
returns a type definition of the appropriate kind. For untyped element nodes,
xs:anyType
is returned as a type definition value.
equals
, =
, and
!=
. It is also useful to be able to test whether one type is a
subtype of another.
fn:subsequence
can work on sequences of component values with no problem.
The general functions fn:string
,
fn:boolean
and fn:not
don't really apply and will
raise errors if applied to component values.fn:deep-equal
over them, we can define
fn:deep-equal
with them. deep-equal
that is stronger than that defined by
XQuery: it requires type equality as well as structural equality.
xs:untyped
and xs:untypedAtomic
), which can be
applied as no-ops. A function can be defined to perform this typed-value
fabrication operation:
run-plugin
can
guarantee that a plugin function executed for some particular piece of the
framework has the expected type, without having to know a priori what that type
is.
sc:facets
accessor
returns sequences of facet component values when applied to simple type
components; it returns the empty sequence otherwise. The accessors already
defined apply to facet component values as well. The sc:name
accessor returns the name of the element used to define the facet
(e.g. xs:enumeration for the enumeration facet), and the standard accessor
fn:data
returns the value of the facet.sc:element-decl
and sc:attribute-decl
accessors return component values when applied to element and attribute nodes,
respectively; otherwise they return empty sequence. In addition, the accessors
already defined apply to these new declaration component values as well. The
sc:type
, sc:complex-type
, and
sc:simple-type
accessors return the type associated with the declaration.
sc:attribute-decl
accessor applies to attribute use component
values.
subtype of
operator did require additions to the lexer and parser
rules. The subtype of
operator was added as an additional kind of
comparison expression; the new sequence type tests were added in parallel to
XPath kind tests. Adding the component kind tests required the same kind of
special handling already required for other names that appear in a similar
context, such as element
or document-node
.
fn:string
was also
implemented over these values to provide a terse representation of them, again,
for debugging purposes. About half the implementation code went into these
debugging APIs.
instance of
and cast
as
expressions would improve usability further:annotation::
axis corresponds to the sc:annotations
accessor.
/
). It then traverses the
schemaElement axis (schemaElement::
) with a name test
(p:outer
), selecting a global
element declaration with the name outer
. The path continues
through the type axis (type::
) with a name test (0
)
that in this case matches a type definition with no name (0
being
the indicator for this case). The path to this point will select the locally
declared anonymous type of the element declaration 'outer'. Finally the path
concludes by traversing the schemaAttribute axis
(schemaAttribute::
) with a name test (p:inner
),
selecting an attribute declaration whose name is 'inner' within the anonymous
type definition. As a whole then, this path selects a particular attribute
declaration of a particular element declaration. The second path means the same
thing, but uses abbreviated syntax.
/
). This time it traverses through the type axis
(type::
) with a name test (p:second
), thus selecting
a global type definition with the name 'second'. The path then traverses the
model axis (model::
) with a name test (sequence
),
thus selecting the model group in the content model of the type,
but only if it is a sequence. The path continues along the schemaElement axis
(schemaElement::
) with a name test (p:duplicate
) and
a positional constraint ([2]
), thus selecting an element
declaration within the sequence that has a name of 'duplicate', but referring
to the second such element within the content model. Finally, the path
traverses the type axis (type::
) with a
wildcard (*
), selecting the type of the given element declaration,
whatever it might be. The fourth path means the same thing, but uses
abbreviated syntax.
sc:element-decl
applies to nodes.
Some accessors, such as sc:type
, apply to component values
also, and so behave somewhat like the schema component axes.
To get the full range of axes available in schema component paths, it would be
necessary to define an accessor function corresponding to each axis, and allow
it to apply to component values. To get the effect of the name tests, XPath
predicates must be applied to the results of the accessor. Some accessors
return simple properties of the components, such as its name. Schema component
paths do not provide for access to the non-component properties. Finally,
schema component paths use the slash (/
) as a syntactic separator
between steps. Since schema components are not nodes, XQuery forbids using them
inside a path (although they can be the last step of a path). A FLWOR
expression, nested function call, or the XQuery 3.0 simple mapping operator
(!
) must be used instead.
Schema Component Paths | Schema Component Accessors |
---|---|
operate on schema components | operate on XQuery values |
apply to schema in isolation | can link between date model items and schema component values |
start at particular schema component, either root of schema or contextually supplied schema component | apply to particular item(), not rooted at top of schema |
path step selects component-valued component properties only | acccessor selects various kinds of properties |
steps combine axis with name test directly | component or name test separate from accessor |
steps combined with slash | chains of accessors cannot be combined with slash: must nest function calls, use FLWOR expressions, or use XQuery 3.0 simple mapping operator instead |
path syntax and semantics similar to XPath, but is not XPath | syntax and semantics are standard XPath |
$context
),
and it was necessary to invent a new accessor to link to the root of the
assembled schema governing the type information for that item
(sc:schema
).
/book/chapter/title/type::*/annotation::*/xs:appinfo/my:special-stuff/@my:type
would switch back and forth between XPaths and schema component paths. Under
this scheme the type axis in the fourth step of the path would start a relative
schema component path with some component as the default. In this case,
the context is the element declaration component for the title
element.
@my:type
at
the end of the path a normal attribute node on the
my:special-stuff
element or is it an attribute declaration?
Careful specification of the switching rules may eliminate ambiguities,
but it won't eliminate confusion for humans reading and writing such
paths. The similarity of schema component paths to XPaths that helps make them
more intuitive in isolation causes difficulty when used in the same context as
XPath. This confusion also makes implementation more difficult: higher levels
of analysis would be required to determine what kinds of operations are
allowable, or to optimize node paths properly.