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:

XdmValue (any sequence) XdmItem (any single item, that is, a sequence of length one) XdmNode (any node) XdmAtomicValue (any atomic value) XdmFunctionItem (a function item) XdmMap (a map) XdmArray (an array) XdmExternalObject (an item that encapsulates a Java or .NET object) XdmEmptySequence (a sequence containing no items)

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 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 Predicates.

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.