IndexedDocument
, containing an "indexed" document element with simple elements as underlying elements.
An element within its context.
An element within its context. In other words, an element as a pair containing the root element (of an underlying element type) and a path (from that root element) to this element. More precisely, this element implementation contains an underlying root element, a Path, and an underlying element found from the root element following the Path. It also contains an optional URI of the containing document, if any.
See the documentation of the mixed-in query API trait(s) for more details on the uniform query API offered by this class.
An IndexedClarkElem(rootElem)
can be seen as one immutable snapshot of an XML tree. All queries (using the ElemApi
uniform
query API) on that snapshot return results within the same snapshot. Take care not to mix up query results from different
snapshots. (This could have been modeled in an alternative design of the class, using a member type, but such a design has
not been chosen.)
Using IndexedClarkElem objects, it is easy to get the ancestry or siblings of an element, as elements of the underlying element type.
Be careful not to create any memory leaks. After all, an element, even a leaf element, typically keeps the entire underlying document element tree as state. Hence the underlying document element tree will always remain in memory if at least one indexed element contains it in its state. (Yet with mutable org.w3c.dom element trees, it is also easy to cause memory leaks. See http://apmblog.compuware.com/2011/04/20/the-top-java-memory-problems-part-1/.)
Having an IndexedClarkElem, it is always possible to re-create the root element as IndexedClarkElem, because the underlying root element is always available. On the other hand, creating an IndexedClarkElem is expensive. Class IndexedClarkElem is optimized for fast querying, at the expense of costly recursive creation.
The optional parent base URI is stored for very fast (optional) base URI computation. This is helpful in an XBRL context, where URI resolution against a base URI is typically a very frequent operation.
The following example code shows how to query for elements with a known ancestry, regardless of the element implementation, if efficiency is not important:
val iBookstore = IndexedClarkElem(bookstore) val iTheBookAuthors = for { iAuthor <- iBookstore.filterElems(withLocalName("Author")) bookPath <- iAuthor.path.findAncestorPath(_.elementNameOption.map(_.localPart) == Some("Book")) iBook <- iBookstore.findElem(_.path == bookPath) if iBook.getChildElem(withLocalName("Title")).elem.text.startsWith("Programming in Scala") } yield iAuthor
In order to use this class, this more formal section can safely be skipped.
The
class can be understood in a precise mathematical sense, as shown below.IndexedClarkElem
Some properties of IndexedClarkElems are as follows:
// All elements (obtained from querying other elements) have the same rootElem iElem.findAllElemsOrSelf.map(_.rootElem).distinct == List(iElem.rootElem) // The correspondence between rootElem, path and elem iElem.findAllElemsOrSelf.forall(e => e.rootElem.findElemOrSelfByPath(e.path).get == e.elem)
The correspondence between queries on IndexedClarkElems and the same queries on the underlying elements is as follows:
// Let p be a function from underlying element type E to Boolean IndexedClarkElem(rootElem).filterElemsOrSelf(e => p(e.elem)).map(_.elem) == rootElem.filterElemsOrSelf(p)
Analogous properties hold for the other query methods.
The underlying element type
Abstract API for "indexed elements".
Abstract API for "indexed elements".
Note how this API removes the need for an API which is like the ElemApi
API, but taking and returning pairs
of elements and paths. This could be seen as that API, re-using ElemApi
instead of adding an extra API similar to it.
These IndexedClarkElemApi
objects "are" the above-mentioned pairs of elements and paths.
The element type itself
The underlying element type
Partial implementation of the abstract API for "indexed elements".
Partial implementation of the abstract API for "indexed elements".
The element type itself
The underlying element type
Document, containing an "indexed" document element.
Document, containing an "indexed" document element.
Note that class IndexedDocument
does not have any query methods for Elem
instances. In particular, the ElemApi
does not
apply to documents. Therefore, given a document, querying for elements (other than the document element itself) always goes
via the document element.
Indexed Scoped element.
Indexed Scoped element. Like IndexedClarkElem
but instead of being and indexing
a ClarkElemApi
, it is and indexes a ScopedElemApi
. Other than that, see the
documentation for IndexedClarkElem
.
The optional parent base URI is stored for very fast (optional) base URI computation. This is helpful in an XBRL context, where URI resolution against a base URI is typically a very frequent operation.
The underlying element type
Abstract API for "indexed Scoped elements".
Abstract API for "indexed Scoped elements".
The element type itself
The underlying element type
Partial implementation of the abstract API for "indexed Scoped elements".
Partial implementation of the abstract API for "indexed Scoped elements".
The element type itself
The underlying element type
Factory object for Elem
instances, where Elem
is a type alias for IndexedScopedElem[simple.Elem]
.
Some XML base support, used in trait IndexedClarkElemLike
, for example, but also potentially useful in application code.
This package contains element representations that contain the "context" of the element. That is, the elements in this package are pairs of a root element and a path (to the actual element itself). The "context" of an element also contains an optional document URI.
An example of where such a representation can be useful is XML Schema. After all, to interpret an element definition in an XML schema, we need context of the element definition to determine the target namespace, or to determine whether the element definition is top level, etc.
Below follows a simple example query, using the uniform query API:
The query for Scala book authors would have been exactly the same if normal
Elem
s had been used instead ofindexed.Elem
s (replacingindexedBookstoreElem
bybookstoreElem
)!