This package (introduced in Saxon 9.9) provides methods to manipulate XDM values using Java 8 streams.

A value in the XDM data model is represented by an instance of {@link net.sf.saxon.s9api.XdmValue}. This is in general a sequence; the members of the sequence are instances of {@link net.sf.saxon.s9api.XdmItem}. {@code XdmItem} is an abstract class; its concrete subclasses include {@link net.sf.saxon.s9api.XdmNode} for nodes, {@link net.sf.saxon.s9api.XdmAtomicValue} for atomic values, {@link net.sf.saxon.s9api.XdmFunctionItem} for function items, {@link net.sf.saxon.s9api.XdmMap} for maps, and {@link net.sf.saxon.s9api.XdmArray} for arrays.

Given an XdmNode N, it is possible to select other nodes using an expression such as"author")).asNode(). The way this works is as follows:

The power of the approach rests in the range of Step implementations available, and the way these can be combined; and in the terminal operations to deliver the result of a stream in a useful way. Although many standard implementations are available, these can be augmented with user-written methods; since a {@code Step} is just a Java 8 {@code Function}, and an {@code XdmStream} is just a Java 8 {@code Stream}, all the standard Java 8 facilities for creating and combining functions and streams are available.


The steps that are available "off the shelf" from the {@link net.sf.saxon.s9api.streams.Steps} class include the following:


Predicates can be used either in the where() method to construct a new Step, or they may be used in the standard Java 8 filter() method to filter the items in a stream. Any predicate may be used in either context. The utility class {@link net.sf.saxon.s9api.streams.Predicates} provides a range of predicates that are particularly suited to XDM navigation.

These predicates include:

Operations on XDM streams

An XdmStream (as delivered by is an implementation of a Java 8 Stream, so all the standard methods on Stream are available: for example filter, map(), flatMap, reduce, collect. Where appropriate, these are specialized to return an XdmStream rather than a generic Stream.

XdmStream provides some additional terminal operations designed to make it convenient to convert the contents of the stream into usable form. These include:

The choice of terminal operation determines the return type (for example asOptionalNode() returns Optional<XdmNode>), and also causes a run-time check that the value actually conforms to these expectations. For example, if asNode() is used, then an unchecked exception occurs if the sequence has a length other than 1 (one), or if its single item is not a node.

Other ways of generating an XdmStream include: