Representation of XDM values
The result of an XPath expression is a value in the XDM data model.
The JAXP API was designed for XPath 1.0, which only has a very limited number of data types (numbers, strings,
booleans, and node-sets). These have close equivalents in Java, so JAXP converts the result of an expression to
the corresponding Java types. This makes the JAXP API problematic when executing expressions that take advantage of the
richer type system introduced in XPath 2.0 and subsequently 3.0 and 3.1: JAXP simply doesn't define what happens if an
XPath expression returns an xs:dateTime
value or a map or array derived from a JSON query. For these reasons, use of
the JAXP API is discouraged.
The native Saxon APIs for Java, C# and C++ all have classes that represent the XDM data model more accurately. The Java and C# implementations are essentially identical in structure so a single description will suffice. The C++ implementation is different.
Values returned by XPath expressions are represented as instances of the XdmValue
class: XdmValue in Java, XdmValue in C#, XdmValue in C++,
XdmValue in PHP,
PyXdmValue in Python.
The XdmValue
class is also used to supply parameters to stylesheets and transformations,
and to return the results of XSLT or XQuery evaluation.
The subclasses of XdmValue
directly reflect the XDM model:
XdmExternalObject
and XdmEmptySequence
are not available in SaxonC.
These objects are generally immutable: at any rate, the API offers no methods to modify them. (It is possible
to subvert this, for example by having an XdmNode
that wraps a DOM node, and then modifying the DOM node: this
is strongly discouraged.)
A variety of methods are provided to convert between these classes and "ordinary" Java, C#, or C++ equivalents. For example:
In Java, an
XdmAtomicValue
can be constructed directly from a Javaboolean
,String
,long
,BigDecimal
, orInstant
(inter alia), and methods such asgetBooleanValue()
andgetStringValue()
are available to convert in the other direction.In C#, an
XdmAtomicValue
can be constructed directly from a C#bool
,string
,long
,decimal
, orDateTime
(inter alia), and methods such asAsBoolean()
andAsDouble()
are available to convert in the other direction.In C++, an
XdmAtomicValue
can be constructed directly from a C++bool
,std::string
, char pointer array,long
,double
,float
orint
, and methods such asgetBooleanValue()
andgetStringValue()
are available to convert in the other direction. Similarly for PHP.In Python, an
PyXdmAtomicValue
can be constructed directly from a Pythonbool
,str
,long
, orfloat
, and methods such asdouble_value()
andinteger_value()
are available to convert in the other direction.
In Java and C#, as an alternative to use of XPath, the select()
(or Select()
)
method on XdmValue
provides powerful
navigation capability around XDM trees. This method takes as argument a
Step (Step in C#) (which is
a function from one node to related nodes) and returns a sequence of nodes as a result. There
is a library (Steps in Java, and Steps in C#)
of Step
functions corresponding to all the XPath axes, and the results of applying a Step
can be filtered using predicates: there is also a library (Predicates in Java, and Predicates in C#) of commonly-used
Predicate
s.
A Java example: if root
is a document node, then root.select(descendant("p")).asXdmValue()
selects all the descendant elements with local name "p" in the form of an XdmValue
.
A C# example: if root
is a document node, then new XdmValue(root.Select(Descendant("p")))
selects all the descendant elements with local name "p" in the form of an XdmValue
.
The XdmNode (XdmNode in C#) class in this hierarchy is implemented as a wrapper
around the lower-level NodeInfo
interface which provides more detailed access to information associated with nodes. The NodeInfo
interface
is designed primarily for internal use within Saxon, whereas XdmNode
is designed for application use.