XDM PRELIMINARY Design Notes


2003-02-03 by Joe Kesselman: First Draft

XDM is intended to be an abstract API for the XPath Data Model. Its goal is to provide a single efficient view of a variety of back-end implementations, ranging from DTM tables to DOMs to databases.

Architecturally, XDM will replace the public DTM APIs. It should certainly be more efficient for non-tabular data, as well as being more maintainable and leaving more flexibility for experimentation with alternative underlying data models. We suspect that it will be more efficient even for the DTM back-end, since it avoids the somewhat baroque process of converting between (API-level) Node Handles and (internal) Node Identifiers.

Cursors

The essential concept behind XDM is that access to the model primarily takes place via Cursor objects, which combine iteration over a set of XPath nodes with accessor methods to examine properties of the current node. Typically, these iterations will occur along XPath's principal axes -- including the "self" axis, which retrieves only the single node at which the iterator was initialized.

Note that the Cursor is a mutable object; it changes its current node each time the next operation is called. This should let us implement very lightweight ("flyweight") implementations of cursors, at the cost of requiring that the higher-level code explicitly generate a new Cursor object if they wish to save a reference to a node.

The XDMCursor interface encapsulates the standardized behavior of cursors, as well as providing factory methods for generating new cursors starting at the current node. An implementation of XDMCursor would be provided for each back-end data model representation that we will wish to access.

The XDMManager interface encapsulates the process of initially loading a document model and retrieving the Cursor for its root node, and (perhaps) for caching models for repeated reference and discarding them once we know we're done with them.

An XDMCursor also serves as a factory for a Tree Walker starting at the current node; see next section.

Walkers/Visitors

The one known use case which Cursors are unable to handle is that of serializing/copying a subtree. These tasks require that we know when nodes are exited as well as when they are entered -- consider the generation of an end-element tag, for example. Our solution here is an alternative form of traversal, a tree-walker/node-visitor pair.

At this time, the Tree Walker performs no filtering; it is the Node Visitor's responsibility to decide which of these events are significant and act upon them. This may be reconsidered in the future, but at this time I expect that letting the visitor make the decision is almost equally efficient for XPath/XSLT purposes.

The XDMTreeWalker encapsulates the concept of walking a document's tree, or a subtree thereof. As it reaches each node it generates a call to an instance of XDMNodeVisitor, passing it an XDMCursor object whose current node is the node being visited.

Implementations of XDMTreeWalker will be provided for each implementation of XDMCursor (and thus for each back-end data model we support). Visitors should be portable among these walkers, and will be coded to perform the specific tasks.

Support Classes

Some of the abstractions now implemented as part of the DTM APIs will have to be moved up to the XDM level. Among these are the Whitespace Filter, Value Sequence, and Model Exception, and the low-level DTM will of course have to be adjusted to use these new interfaces. They shouldn't have to change very much.

These are currently prototyped as XDMWSFilter, XDMSequence, and XDMException (which has a subclass XDMConfigurationException).

Design Status

First-draft versions of these interfaces have been coded, in the org.apache.xml.xdm package. There are still some issues to be resolved; these are flagged in the code with our usual %REVIEW%, %OPT% and %BUG% eye-catchers.

We expect these interfaces will continue to evolve somewhat, driven by implementation experience, as we discover features to be unnecessary or missing.

Implementation Status

At this time, the basic code framework has been sketched, and we have a version of XDM which runs on top of DTM Traversers. This is not maximally efficient; it was just maximally fast to prototype. I have also adapted a few of the DTM Unit Tests -- simple as they are -- to run against XDM as an initial validation.

There are still some issues to be resolved; these are flagged in the code with our usual %REVIEW%, %OPT% and %BUG% eye-catchers.

Implementation Plan

Our next step will be to try adapting a copy of Xalan to run against XDM rather than DTM, replacing Node Handles and DTM Iterators with Cursors and Tree Walkers. This should not be difficult, but will be time-consuming and poses risks of human error. I do not currently have a sizing estimate for this task.

After that's running, we will come back and start optimizing XDM, phasing out Node Handles and letting XDM become our public model API. We will also begin writing XDM wrappers around some of the other models -- such as an XDM for DOM based on the DOM2DTM2 experiment.