Creation of cursors is done either via SMInputFactory (for root cursors), or via other cursors (for all child and descendant cursors): each time an cursor points to START_ELEMENT, a new child cursor (flat or nested) can be created.
The main benefit of cursors is scoped access with serialization. but serialized (document-order) access to XML content – this is required to be able to use basic Stax XMLStreamReader without additional buffering.
What this means is that:
1#. It is always safe to pass a child cursor to another processing component: that component can only access entries within scope of the cursor; and all this without that component having to keep track of the nesting of elements.
2 #. Access via multiple dependant cursors (child, parent) is serialized such that underlying access is always in document order.
All normal access to the event information (name of the element, attributes, attribute values, textual content, processing instruction target and so on) is accessible via an the active cursor (one that is currently pointing to an underlying Stax event). At any given point, there will be just one such cursor. Although there are methods to check if an cursor is at such valid point, this is seldom needed: as long as access is done right after advancing an cursor this works as expecteda cursor, it "just works".
In addition to the two main types of cursors, there is also support for simple configurable filtering of events visible using the cursors. For example, it is trivially easy to construct an element-only cursor (one that ignores all other event types but START_ELEMENT (and for flat cursors, END_ELEMENT)):
SMCursor SMInputCursor nestedTextIter = currentCursor.childElementCursor();
SMCursor SMInputCursor nestedTextIter = currentCursor.descendantElementCursor();
(first call creates a nested cursor, and second a flat cursor)
And for more configurable filtering:
SMCursor SMInputCursor nestedTextIter = currentCursor.childCursor(new SimpleFilter(...));
SMCursor SMInputCursor nestedTextIter = currentCursor.descendantCursor(new SimpleFilter(...));
Tracking can be enabled on per-cursor basis: and it takes effect for all child (and descendant) cursors of the cursor. This is because there is no way to retrieve information of events that have been passed already.
(to be completed)
(new with StaxMate 2.0 – to be complete)
There are some additional convenience methods, for doing commonly needed thins like:
- Get me all the text contained within the element this cursor points to (ignoring all elements, comments, processing instructions, if any)
(to be completed)