eu.cdevreeze.yaidom

indexed

package indexed

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).

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:

// Note the import of package indexed, and not of its members. That is indeed a best practice!
import eu.cdevreeze.yaidom.indexed

val indexedBookstoreElem = indexed.Elem(bookstoreElem)

val scalaBookAuthors =
  for {
    bookElem <- indexedBookstoreElem \ EName("{http://bookstore/book}Book")
    if (bookElem \@ EName("ISBN")) == Some("978-0981531649")
    authorElem <- bookElem \\ EName("{http://bookstore/author}Author")
  } yield authorElem

The query for Scala book authors would have been exactly the same if normal Elems had been used instead of indexed.Elems (replacing indexedBookstoreElem by bookstoreElem)!

Linear Supertypes
AnyRef, Any
Ordering
  1. Alphabetic
  2. By inheritance
Inherited
  1. indexed
  2. AnyRef
  3. Any
  1. Hide All
  2. Show all
Learn more about member selection
Visibility
  1. Public
  2. All

Type Members

  1. final class Document extends DocumentApi[Elem] with Immutable

    Document, containing an "indexed" document element.

    Document, containing an "indexed" document element.

    Note that class Document 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.

  2. final class Elem extends ScopedElemLike[Elem] with IsNavigable[Elem] with Immutable

    An element within its context.

    An element within its context. In other words, an element as a pair containing the root element (as eu.cdevreeze.yaidom.simple.Elem) and a path (from that root element) to this element.

    See the documentation of the mixed-in query API trait(s) for more details on the uniform query API offered by this class.

    An indexed.Elem(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.)

    Example

    Below follows an example. This example queries for all book elements having at least Jeffrey Ullman as author. It can be written as follows, assuming a book store Document with the appropriate structure:

    val bookstoreElm = indexed.Document(doc).documentElement
    require(bookstoreElm.localName == "Bookstore")
    
    val ullmanBookElms =
      for {
        authorElm <- bookstoreElm filterElems { e =>
          (e.localName == "Author") &&
          ((e.getChildElem(_.localName == "First_Name")).text == "Jeffrey") &&
          ((e.getChildElem(_.localName == "Last_Name")).text == "Ullman")
        }
        bookElm <- authorElm.path findAncestorPath { _.elementNameOption == Some(EName("Book")) } map { path =>
          bookstoreElm.getElemOrSelfByPath(path)
        }
      } yield bookElm

    Note how we found an ancestor (Book) element of an Author element by first finding the appropriate ancestor path, and then querying the bookstore element for the element at that path. So we remembered the document element (as indexed element), and used that "snapshot" to navigate to elements at given ancestor paths of other elements. This is certainly more efficient than re-indexing (using an indexed element factory method).

    Elem more formally

    In order to get started using the class, this more formal section can safely be skipped. On the other hand, this section may provide a deeper understanding of the class.

    Let indexedRootElem be a root element, so indexedRootElem.path == Path.Root.

    Then, first of all, we have:

    indexedRootElem.elem == indexedRootElem.rootElem

    Given:

    val elems = indexedRootElem.findAllElemsOrSelf

    the following (rather obvious) properties hold for indexed elements:

    elems forall (e => e.rootElem == indexedRootElem.rootElem)
    
    elems forall { e => e.rootElem.findElemOrSelfByPath(e.path) == Some(e.elem) }

    The properties above hold for findAllElemsOrSelf, so they certainly hold for the other child/descendant/descendant-or-self element query methods.

Value Members

  1. object Document

  2. object Elem

Inherited from AnyRef

Inherited from Any

Ungrouped