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
This is in general a sequence; the members of the sequence are instances of
XdmItem is an abstract class; its concrete subclasses include
XdmAtomicValue for atomic values,
for function items,
XdmMap for maps, and
N, it is possible to select other nodes using an expression
N.select(child("author")).asNode(). The way this works is as follows:
select()method (which applies to any
XdmValue, not only an
XdmNode) takes as its argument a
Step, and returns as its result an
Stepis a function that takes an
XdmItemas input, and returns a stream of items as its result; the
select()method combines these streams into a single stream (in much the same way as the Java 8
flatMap()operation) and returns the result.
child("author")invokes a static method in class
Steps, which delivers a
Stepwhose effect is to find the children of a supplied node that have local name
"author", returning these as a Stream. The
Stepsclass provides a large collection of useful implementations of
Step, including support for all the XPath axes (parent, child, descendant, following-sibling and so on).
- The class
XdmStream(which will typically not be used explicitly) implements the standard Java 8
java.util.streams.Streamclass; it does so by wrapping a standard Java 8 stream and delegating all standard methods to the wrapped stream. By subclassing the standard
Streaminterface, however, it is able to supply additional methods appropriate to streams of XDM items. For example, the
asNode()example terminates the Stream pipeline by converting the result of the stream to a single
XdmNodevalue (an unchecked exception occurs if the content of the stream is anything other than a single node).
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;
Step is just a Java 8
Function, and an
XdmStream is just a Java 8
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
class include the following:
For each of the 13 XPath axes, taking
childas an example, four
Stepimplementations are provided:
child()selects all the children of a node.
child("lname")selects all the children of a node that have the local name "lname".
child("ns", "lname")selects all the children of a node that have the namespace URI "ns" and local name "lname".
child(predicate)selects all the children of a node that satisfy the given predicate. The predicate may be any Java 8
java.util.functions.Predicate, but the class
Predicatesprovides some off-the-shelf predicates that are particularly designed for navigating XDM information.
Tmay be combined into a single step using the
thenmethod: for example
More generally, any sequence of steps may be combined using the
path()function, for example
path(child("table"), child("thead"), child("trow"), attribute("class"))
Where the steps in a path are the most commonly used variety, a path may be written using an abbreviated notation:
path("table", "thead", "trow", "@class")is equivalent to the previous example.
The results of two steps may also be concatenated: for example
child("author").cat(child("editor"))concatenates the results of the two steps into a single stream.
atomize()step reduces nodes (and arrays) to atomic values, as defined in the XPath specification.
S.where(P)is also a
Step, which selects those elements selected by
P. For example
child().where(isElement())selects those children of the starting node that are elements. (But this particular example can be written more easily as
Predicates can be used either in the
where() method to construct a new
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
provides a range of predicates that are particularly suited to XDM navigation.
These predicates include:
isArray()etc to test whether an
XdmItemis a particular kind of item;
isText()etc to test the kind of a node;
- The predicate
hasType()to test whether an item matches a specific item type: for example
hasType(ItemType.XS_DATE_TIME)tests whether it is an instance of
- The predicate
eq("string")tests whether the string value of the item is equal to "string"
- The predicate
eq(XdmAtomicValue)performs a typed comparison, for example comparing two values as numbers
- The predicate
matchesRegex("regex")tests whether the string value of the item matches the regular expression "regex"
some(S, P)is a predicate that returns true if some item returned by
every(S, P)tests if all items returned by
P. For example
some(attribute("id"), eq("A123"))is true for an element that has an
idattribute equal to "A123". This particular condition can also be expressed more concisely as
Operations on XDM streams
XdmStream (as delivered by
XdmValue.select(step)) is an implementation of
a Java 8 Stream, so all the standard methods on
Stream are available: for example
collect. Where appropriate, these
are specialized to return an
XdmStream rather than a generic
XdmStream provides some additional terminal operations designed to make it convenient to convert
the contents of the stream into usable form. These include:
first()- deliver the first item of the stream
last()- deliver the last item of the stream
at()- deliver the item at position N the stream
exists()- return true if the stream is non-empty
subStream()- deliver a stream containing a subsequence of the input stream
asXdmValue()- deliver the contents as an
asList()- deliver the contents as a
asListOfNodes()- deliver the contents as a
asOptionalNode()- deliver the contents as an
asNode()- deliver the contents as a single
asListOfAtomic()- deliver the contents as a
asOptionalAtomic()- deliver the contents as an
asAtomic()- deliver the contents as a single
asOptionalString()- deliver the contents as an
Optional<String>by taking the string value of each item
asString()- deliver the contents as a single
The choice of terminal operation determines the return type (for example
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
- As the result of an XPath expression, using the method
- As the result of an XQuery expression, using the method
- As the result of
Class Summary Class Description PredicatesThis non-instantiable class provides a number of useful implementations of the
Predicateinterface, designed for use when navigating streams of XDM items.
Step<T extends XdmItem>A
Stepis a function that can be applied to an item to return a stream of items.
StepsThis non-instantiable class provides a number of useful implementations of the
Stepinterface, used to navigate XDM trees, typically as an argument to
XdmCollectorsThis class contains a number of static methods that deliver implementations of the
Collectorinterface suitable for use with streams processing XDM nodes and other items.
XdmStream<T extends XdmItem>XdmStream extends the capabilities of the standard JDK
Exception Summary Exception Description XdmCollectors.MultipleItemExceptionUnchecked exception that occurs when a collector method such as
XdmCollectors.asOptionalNode()is called, and the sequence contains more than one item.