The internal mechanisms and API for pull processing have been substantially rewritten in this release.
There is a new method iterateEvents()
on the Expression
class, which evaluates
the expression and returns its result as a sequence of PullEvent
objects. A PullEvent
can be an Item
(that is, a NodeInfo
or AtomicValue
). It can also
be a StartElement, EndElement, StartDocument, or EndDocument event. Within the content of a document or element,
the child nodes can be represented either as complete nodes (including element nodes, and potentially even document
nodes, in which case the document wrapper should be ignored) or as nested event sequences using further StartElement
and EndElement events.
An EventIterator
is also a PullEvent
, so a stream of events can contain nested
streams. If you want to process the events without having to handle this nesting, you can flatten the sequence
by calling the static method EventStackIterator.flatten()
.
To serialize the results of a query, there is a static method EventIteratorToReceiver.copy()
which
reads the events from a pull pipeline (an EventIterator
), and pushes them to a push pipeline (a
Receiver
). However, if you are serializing the results then it probably makes sense in most cases
to evaluate the query in push mode to start with.
A sequence in which all the PullEvents
are Item
objects is called a composed
sequence. A sequence in which all document and element nodes are split into their constituent events is called
a decomposed sequence. You can turn any sequence of PullEvents into a fully composed sequence by wrapping it in
a SequenceComposer
. This will physically construct any document or element nodes that were represented
in the sequence in decomposed form. Similarly, you can turn any sequence into a fully decomposed sequence by wrapping it in
a Decomposer
.