Converter from A
(which can be anything) to eu.cdevreeze.yaidom.Document.
Converter from A
(which can be anything) to eu.cdevreeze.yaidom.Elem.
Namespace declarations (and undeclarations), typically at the level of one element.
Builder of a yaidom Document.
Document
.
Converter from eu.cdevreeze.yaidom.Document to A
(which can be anything, such as a DOM Document
).
Expanded name.
Element node.
API for elements as containers of elements, each having a name and possible attributes.
Builder for elements.
Converter from eu.cdevreeze.yaidom.Elem to A
(which can be anything, such as a DOM Element
).
API and implementation trait for elements as containers of elements, each having a name and possible attributes.
Unique identification of a descendant (or self) Elem
given a root Elem
.
Builder for ElemPath
instances.
An entity reference.
API and implementation trait for elements that can be asked for the ancestor elements, if any.
Trait defining the contract for elements as text containers.
Immutable XML node.
DSL to build Elem
s (or Document
s) without having to pass parent Scope
s around.
API for elements as containers of elements, as element nodes in a node tree.
API and implementation trait for elements as containers of elements, as element nodes in a node tree.
API for elements as containers of elements, each having a name and possible attributes, as well as an "element path" from the root element.
API and implementation trait for elements as containers of elements, each having a name and possible attributes, as well as an "element path" from the root element.
Qualified name.
Scope mapping prefixes to namespace URIs, as well as holding an optional default namespace.
"Updatable" element.
"Updatable" element.
This singleton object contains a DSL to easily create deeply nested Elems.
Generator for parsers of "tree representation" expressions.
Support for conversions from/to yaidom.
Wrapper around class org.w3c.dom.Element
, adapting it to the eu.cdevreeze.yaidom.ElemLike API.
This package contains element representations that contain the "context" of the element.
Support for parsing XML into yaidom Document
s and Elem
s.
Support for "printing" yaidom Document
s and Elem
s.
This package contains element representations that can be compared for (some notion of "value") equality, unlike normal yaidom nodes.
XLinks, wrapping an eu.cdevreeze.yaidom.Elem.
Introduction
Yet another immutable DOM-like API. Hence the name yaidom. This is not an implementation of W3C DOM. Instead, this is a Scala-ish DOM-like API. Foremost, that means that this API is centered around Scala Collections of immutable nodes.
By design, some characteristics of this API are:
for
comprehensions, manipulating immutable Scala collections. It should often even be attractive to use this API instead of XPath, XSLT and/or XQuery, at the cost of somewhat more verbosity, loss of (schema) typing information, and loss of a standard XML query language. Much of the attraction of yaidom for querying lies in its simplicity. That is, understanding the Scala Collections API (from the perspective of a user) is almost all that is needed for understanding querying in yaidom. In comparison, XSLT is known to be a hard language to master.Option
s over nulls. It is clear from method and variable names whereOption
s are used. Also, methods whose names start with "find" tend to returnOption
s.The yaidom API is most suitable for processing "data-oriented" XML, roughly having the following properties:
That is not to say that yaidom can only be used for processing such "data-oriented" XML.
Yaidom is not a very ambitious API:
Yaidom has been inspired by Anti-XML. The Anti-XML library tackles some weaknesses of Scala's standard XML API, w.r.t. robustness, ease of use and performance. Yaidom tries to achieve the same (in a different way), but yaidom is less ambitious, foremost in not offering any XPath(-like) support.
Different element types in yaidom
Yaidom considers XML to be trees of nodes, rather than text strings obeying "XML rules". Think InfoSet and DOM, rather than the XML spec. By considering XML to be node trees, round-tripping (from XML string to DOM-like tree, and back) cannot be lossless. Again, if lossless round-tripping is important (like is the case for XML editors), yaidom (like DOM) may not be a good fit.
Yet yaidom has more than just one type of (DOM-like) element. First of all, yaidom distinguishes between:
Concrete element classes in yaidom that mix in trait eu.cdevreeze.yaidom.ParentElemLike (or sub-traits) are:
Elem
s know about in-scope namespaces but not about (own) namespace declarations,ElemBuilder
s know about (own) namespace declarations but not about in-scope namespaces.ParentElemLike
"views" backed byorg.w3c.dom.Element
elements. These views are mutable and "volatile", so far less safe to use than the immutable elements mentioned above.Often these different element types can be used well together. For example:
In the spirit of the "DOM node wrappers", one could easily come up with similar wrappers around JDOM, XOM, etc., mixing in trait eu.cdevreeze.yaidom.ParentElemLike (or subtraits). Yaidom does not offer these wrappers, but some test cases show that such wrappers are easy to develop.
Examples
Below follow some examples. The first example queries for all book elements having a price below 90. It can be written as follows, assuming a book store
Document
with the appropriate structure:The for-comprehension is equivalent to:
All books having (at least) Jeffrey Ullman as author can be found as follows:
An alternative way to write the same query, but using eu.cdevreeze.yaidom.ElemPath instances instead, is as follows:
This is conceptually similar to navigating in XPath to the grandparent nodes of the matching Author elements.
Alternatively, using eu.cdevreeze.yaidom.indexed.Elem instances, we could write:
What's in the API, and what are the dependencies?
This package contains the following parts, in order of dependencies (starting with the class without any dependencies):
UpdatableElemLike
andHasText
).Scope
s (whereas theNode
s that they create all must have a fixedScope
), so node builders are indeed intended to be handy for creation of node trees. At the same level are eu.cdevreeze.yaidom.ConverterToElem, eu.cdevreeze.yaidom.ElemConverter, etc.Dependencies are all uni-directional. All types in this package are (deeply) immutable. That holds even for the eu.cdevreeze.yaidom.NodeBuilder instances.
Parsing and printing of XML are not handled in this package. Even the
toString
methods for nodes use theNodeBuilder
DSL syntax rather than XML string syntax. Hence the complex details of character escaping, "ignorable whitespace" etc. are not handled in this package. Parsing and printing of XML are offered by the eu.cdevreeze.yaidom.parse and eu.cdevreeze.yaidom.print subpackages, which depend on the eu.cdevreeze.yaidom.convert subpackage. Those subpackages depend on this package, and not the other way around. Put differently, they are in this namespace.Yaidom also offers packages eu.cdevreeze.yaidom.resolved, eu.cdevreeze.yaidom.indexed and eu.cdevreeze.yaidom.xlink. The
resolved
package offers "bare bones" elements, stripped down to "essentials" (replacing prefixes by namespace URIs, removing comments, etc.), such that those elements can be compared for some notion of equality. Theindexed
package offers immutable elements knowing their ancestry. Thexlink
package offers some basic XLink support.There is also a package eu.cdevreeze.yaidom.dom for
ElemLike
wrappers around (mutable!) DOM elements.