Common super-class for IndexedClarkElem and IndexedScopedElem.
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(underlyingRootElem) 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, 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/.)
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) iElem.findAllElemsOrSelf.map(_.underlyingRootElem).distinct == List(iElem.underlyingRootElem) // The correspondence between rootElem, path and elem iElem.findAllElemsOrSelf.forall(e => e.rootElem.findElemOrSelfByPath(e.path).get == e) iElem.findAllElemsOrSelf.forall(e => e.underlyingRootElem.findElemOrSelfByPath(e.path).get == e.underlyingElem)
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 iElem.rootElem.filterElemsOrSelf(e => p(e.underlyingElem)).map(_.underlyingElem) == iElem.underlyingRootElem.filterElemsOrSelf(p)
Analogous properties hold for the other query methods.
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.
Factory object for Elem instances, where Elem is a type alias for IndexedScopedElem[simple.Elem].
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
Elems had been used instead ofindexed.Elems (replacingindexedBookstoreElembybookstoreElem)!There is no explicit functional update support for the indexed elements in this package. Of course the underlying elements can be functionally updated (for element implementations that offer such update support), and indexed elements can be created from the update results, but this is hardly efficient functional update support.
One problem with efficient functional updates for indexed elements is that updating just one child element means that all subsequent child elements may have to be updated as well, adapting the stored paths. In comparison, simple elements do not have this restriction, and can be updated in isolation. Hence the functional update support for simple elements but not for the different indexed element implementations.