Message-ID: <2028257224.22809.1394233035131.JavaMail.firstname.lastname@example.org> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_22808_309587294.1394233035131" ------=_Part_22808_309587294.1394233035131 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
The input side of StaxMate is bui=
lt on concept of multiple synchronized cursors. Cursors ca=
n be thought of as pointers that can only move forward over a scope: a subs=
et of the document they can traverse over. Scope is either a sub-tree for a=
given element (including all of its ancestors, children and grand-children=
), or a "slice" that contains just immediate children. That is, a=
cursor can only traverse the sub-tree it was created for.
During tra= versal, you can create new child cursors for existing cursors.
The only limitation regarding cursor usage is that only one of cursors i=
s ever active; that is, points to valid content to be accessed.
A cur= sor is automatically activated when it is created, or when it is advanced. = Cursor gets completely deactivated when it traverses through its scope: thi= s also happens for all child cursors when the parent cursor is advanced (be= cause it has to skip the sub-tree(s) its child cursors would traverse).
If this sounds confusing, please refer to Tutorial page, and sample usage: sample code should be very in= tuitive and show the reasons for above-mentioned restrictions.=20
All cursors extend SMInputCursor base class; and most A= PI is defined at this class. But there are 2 main flavours of cursors, impl= emented as sub-classes:=20
Creation of cursors is done either via SMInputFactory (= for root cursors), or via other cursors (for all child and descendant curso= rs): each time an cursor points to START_ELEMENT, a new child cursor (flat = or nested) can be created.=20
The main benefit of cursors is scoped access but serialized (document-or=
der) access to XML content =E2=80=93 this is required to be able to use bas=
ic Stax XMLStreamReader without additional buffering.
What this means= is that:
#. It is always safe to pass a child cursor to another processing compon=
ent: 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 ele=
#. Access via multiple dependant cursors (child, parent) is se= rialized such that underlying access is always in document order.
Point 2. means that when a component is done with cursor (at any point; = including not using it at all), there is no need to manually "fast for= ward" through events that cursor would be seeing. Parent cursor takes = care of skipping through events not needed, automatically, when parent curs= or itself is advanced. This advancement will then invalidate all child curs= ors (since cursor has advanced past point where they would be valid), and e= nsuring they can not be advanced any more.=20
All normal access to the event information (name of the element, attribu= tes, attribute values, textual content, processing instruction target and s= o on) is accessible via the active cursor (one that is currently pointing t= o an underlying Stax event). At any given point, there will be just one suc= h 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 advanc= ing a cursor, it "just works".=20
In addition to the two main types of cursors, there is also support for = simple configurable filtering of events visible using the cursors. For exam= ple, it is trivially easy to construct an element-only cursor (one that ign= ores all other event types but START_ELEMENT (and for flat cursors, END_ELE= MENT)):=20
SMInputCursor nestedTextIter =3D currentCursor.childElementCursor();
SMInputCursor nestedTextIter =3D currentCursor.descendantElementCursor(= );
(first call creates a nested cursor, and second a flat cursor)
And= for more configurable filtering:
SMInputCursor nestedTextIter =3D currentCursor.childCursor(new SimpleFi=
SMInputCursor nestedTextIter =3D currentCursor.descendant= Cursor(new SimpleFilter(...));
you can specify your own filtering rules (SimpleFilter strictly bases fi= ltering on event types; simple, fast and usually sufficient =E2=80=93 it's = used to implement text and element filters).=20
Tracking is a simple yet powerful mechanism for persisting some subset o= f information for the currently active branch of the logical XML content tr= ee. For example, you may want to know element and attribute names, and all = attribute values, of all the parents of the element an cursor currently poi= nts to; but you need not keep track of any other ancestor information. This= may be decent compromise between full in-memory DOM and transient streamin= g processing.=20
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.=20
(to be completed)=20
(new with StaxMate 2.0 =E2=80=93 to be complete)=20
There are some additional convenience methods, for doing commonly needed= thins like:=20
(to be completed)