The element type itself.
The element type itself. It must be restricted to a sub-type of the query API trait in question.
Concrete element classes will restrict this type to that element class itself.
The node type, that is a super-type of the element type, but also of corresponding text node types etc.
The node type, that is a super-type of the element type, but also of corresponding text node types etc.
Shorthand for filterChildElems(p)
.
Shorthand for attributeOption(expandedName)
.
Shorthand for attributeOption(expandedName)
.
Shorthand for filterElemsOrSelf(p)
.
Shorthand for findTopmostElemsOrSelf(p)
.
Returns the value of the attribute with the given expanded name, and throws an exception otherwise.
Returns the value of the attribute with the given expanded name, and throws an exception otherwise.
Returns the value of the attribute with the given expanded name, if any, wrapped in an Option
.
Returns the value of the attribute with the given expanded name, if any, wrapped in an Option
.
Finds the child node index of the given path entry, or -1 if not found.
Finds the child node index of the given path entry, or -1 if not found. More precisely, returns:
collectChildNodeIndexes(Set(pathEntry)).getOrElse(pathEntry, -1)
Returns the child nodes of this element, in the correct order
Returns the child nodes of this element, in the correct order
Returns a copy where adjacent text nodes have been combined into one text node, throughout the node tree
Returns a copy where adjacent text nodes have been combined into one text node, throughout the node tree.
Returns a copy where adjacent text nodes have been combined into one text node, throughout the node tree. After combining the adjacent text nodes, all text nodes are transformed by calling the passed function.
Returns a copy where adjacent text nodes have been combined into one text node, and where all text is normalized, throughout the node tree.
Returns a copy where adjacent text nodes have been combined into one text node, and where all
text is normalized, throughout the node tree. Same as calling coalesceAllAdjacentText
followed by normalizeAllText
,
but more efficient.
Filters the child elements with the given path entries, and returns a Map from the path entries of those filtered elements to the child node indexes.
Filters the child elements with the given path entries, and returns a Map from the path entries of those filtered elements to the child node indexes. The result Map has no entries for path entries that cannot be resolved. This method should be fast, especially if the passed path entry set is small.
Returns the child elements obeying the given predicate.
Returns the descendant elements obeying the given predicate.
Returns the descendant-or-self elements obeying the given predicate.
Returns the descendant-or-self elements obeying the given predicate. This method could be defined as:
def filterElemsOrSelf(p: ThisElem => Boolean): immutable.IndexedSeq[ThisElem] = Vector(this).filter(p) ++ (this.findAllChildElems flatMap (_.filterElemsOrSelf(p)))
It can be proven that the result is equivalent to findAllElemsOrSelf filter p
.
Returns the element children
Returns all child elements paired with their path entries.
Returns all child elements paired with their path entries.
This method is final, so more efficient implementations for sub-types are not supported. This implementation is only efficient if finding all child elements as well as computing their resolved names is efficient. That is not the case for DOM wrappers or Scala XML Elem wrappers (due to their expensive Scope computations). On the other hand, those wrapper element implementations are convenient, but not intended for heavy use in production. Hence, this method should typically be fast enough.
Returns all descendant elements (not including this element).
Returns this element followed by all descendant elements (that is, the descendant-or-self elements).
Returns the first found attribute value of an attribute with the given local name, if any, wrapped in an Option
.
Returns the first found attribute value of an attribute with the given local name, if any, wrapped in an Option
.
Because of differing namespaces, it is possible that more than one such attribute exists, although this is not often the case.
Returns the first found child element obeying the given predicate, if any, wrapped in an Option
.
Finds the child element with the given Path.Entry
(where this element is the root), if any, wrapped in an Option
.
Finds the child element with the given Path.Entry
(where this element is the root), if any, wrapped in an Option
.
This method is final, so more efficient implementations for sub-types are not supported. This implementation is only efficient if finding all child elements as well as computing their resolved names is efficient. That is not the case for DOM wrappers or Scala XML Elem wrappers (due to their expensive Scope computations). On the other hand, those wrapper element implementations are convenient, but not intended for heavy use in production. Hence, this method should typically be fast enough.
Returns the first found (topmost) descendant element obeying the given predicate, if any, wrapped in an Option
.
Returns the first found (topmost) descendant-or-self element obeying the given predicate, if any, wrapped in an Option
.
Finds the element with the given Path
(where this element is the root), if any, wrapped in an Option
.
Finds the element with the given Path
(where this element is the root), if any, wrapped in an Option
.
That is, returns:
findReverseAncestryOrSelfByPath(path).map(_.last)
Note that for each non-empty Path, we have:
findElemOrSelfByPath(path) == findChildElemByPathEntry(path.firstEntry) flatMap (e => e.findElemOrSelfByPath(path.withoutFirstEntry))
Finds the reversed ancestry-or-self of the element with the given Path
(where this element is the root),
wrapped in an Option.
Finds the reversed ancestry-or-self of the element with the given Path
(where this element is the root),
wrapped in an Option. None is returned if no element can be found at the given Path.
Hence, the resulting element collection, if any, starts with this element and ends with the element at the given Path, relative to this element.
This method comes in handy for (efficiently) computing base URIs, where the (reverse) ancestry-or-self is needed as input.
Returns the descendant elements obeying the given predicate that have no ancestor obeying the predicate.
Returns the descendant-or-self elements obeying the given predicate, such that no ancestor obeys the predicate.
Returns the descendant-or-self elements obeying the given predicate, such that no ancestor obeys the predicate. This method could be defined as:
def findTopmostElemsOrSelf(p: ThisElem => Boolean): immutable.IndexedSeq[ThisElem] = if (p(this)) Vector(this) else (this.findAllChildElems flatMap (_.findTopmostElemsOrSelf(p)))
Returns the single child element obeying the given predicate, and throws an exception otherwise.
Returns (the equivalent of) findChildElemByPathEntry(entry).get
Returns (the equivalent of) findChildElemByPathEntry(entry).get
Returns (the equivalent of) findElemOrSelfByPath(path).get
Returns (the equivalent of) findElemOrSelfByPath(path).get
Returns (the equivalent of) findReverseAncestryOrSelfByPath(path).get
Returns (the equivalent of) findReverseAncestryOrSelfByPath(path).get
The local name, that is, the local part of the EName
The local name, that is, the local part of the EName
Returns a copy in which the child at the given position (0-based) has been removed.
Returns a copy in which the child at the given position (0-based) has been removed.
Throws an exception if index >= children.size
.
Returns a copy where text nodes have been normalized, throughout the node tree.
Returns a copy where text nodes have been normalized, throughout the node tree.
Note that it makes little sense to call this method before coalesceAllAdjacentText
.
Returns XmlStringUtils.normalizeString(text)
.
Returns XmlStringUtils.normalizeString(text)
.
Returns a copy in which the given child has been inserted at the end
Returns a copy in which the given child has been inserted at the end
Returns a copy in which the given child has been inserted at the given position (0-based).
Returns a copy in which the given child has been inserted at the given position (0-based).
If index == children.size
, adds the element at the end. If index > children.size
, throws an exception.
Afterwards, the resulting element indeed has the given child at position index
(0-based).
Returns a copy in which the given child, if any, has been inserted at the end.
Returns a copy in which the given child, if any, has been inserted at the end.
That is, returns plusChild(childOption.get)
if the given optional child element is non-empty.
Returns a copy in which the given child, if any, has been inserted at the given position (0-based).
Returns a copy in which the given child, if any, has been inserted at the given position (0-based).
That is, returns plusChild(index, childOption.get)
if the given optional child element is non-empty.
Returns a copy in which the given children have been inserted at the end
Returns a copy in which the given children have been inserted at the end
Returns a copy where inter-element whitespace has been removed, throughout the node tree.
Returns a copy where inter-element whitespace has been removed, throughout the node tree.
That is, for each descendant-or-self element determines if it has at least one child element and no non-whitespace text child nodes, and if so, removes all (whitespace) text children.
This method is useful if it is known that whitespace around element nodes is used for formatting purposes, and (in the absence of an XML Schema or DTD) can therefore be treated as "ignorable whitespace". In the case of "mixed content" (if text around element nodes is not all whitespace), this method will not remove any text children of the parent element.
XML space attributes (xml:space) are not respected by this method. If such whitespace preservation functionality is needed, it can be written as a transformation where for specific elements this method is not called.
The resolved attributes of the element as mapping from ENames to values
The resolved attributes of the element as mapping from ENames to values
The EName of the element
The EName of the element
Returns the concatenation of the texts of text children, including whitespace.
Returns the concatenation of the texts of text children, including whitespace. Non-text children are ignored. If there are no text children, the empty string is returned.
Returns the text children
This element itself.
This element itself.
Returns a copy where text nodes have been transformed, throughout the node tree.
Returns the same element, except that child elements have been replaced by applying the given function.
Returns the same element, except that child elements have been replaced by applying the given function. Non-element child nodes occur in the result element unaltered.
That is, returns the equivalent of:
val newChildren = children map { case e: E => f(e) case n: N => n } withChildren(newChildren)
Returns the same element, except that child elements have been replaced by applying the given function.
Returns the same element, except that child elements have been replaced by applying the given function. Non-element child nodes occur in the result element unaltered.
That is, returns the equivalent of:
val newChildren = children flatMap { case e: E => f(e) case n: N => Vector(n) } withChildren(newChildren)
Transforms the element by applying the given function to all its descendant elements, in a bottom-up manner.
Transforms the element by applying the given function to all its descendant elements, in a bottom-up manner.
That is, returns the equivalent of:
transformChildElems (e => e.transformElemsOrSelf(f))
Transforms the element by applying the given function to all its descendant-or-self elements, in a bottom-up manner.
Transforms the element by applying the given function to all its descendant-or-self elements, in a bottom-up manner.
That is, returns the equivalent of:
f(transformChildElems (e => e.transformElemsOrSelf(f)))
In other words, returns the equivalent of:
f(transformElems(f))
Transforms each descendant element to a node sequence by applying the given function to all its descendant-or-self elements, in a bottom-up manner.
Transforms each descendant element to a node sequence by applying the given function to all its descendant-or-self elements, in a bottom-up manner.
That is, returns the equivalent of:
f(transformChildElemsToNodeSeq(e => e.transformElemsOrSelfToNodeSeq(f)))
In other words, returns the equivalent of:
f(transformElemsToNodeSeq(f))
Transforms each descendant element to a node sequence by applying the given function to all its descendant elements, in a bottom-up manner.
Transforms each descendant element to a node sequence by applying the given function to all its descendant elements, in a bottom-up manner. The function is not applied to this element itself.
That is, returns the equivalent of:
transformChildElemsToNodeSeq(e => e.transformElemsOrSelfToNodeSeq(f))
It is equivalent to the following expression:
transformElemsOrSelf { e => e.transformChildElemsToNodeSeq(che => f(che)) }
Returns text.trim
.
Returns text.trim
.
Returns updateChildElem(pathEntry) { e => newElem }
Returns updateChildElem(pathEntry) { e => newElem }
Functionally updates the tree with this element as root element, by applying the passed function to the element that has the given eu.cdevreeze.yaidom.core.Path.Entry (compared to this element as root).
Functionally updates the tree with this element as root element, by applying the passed function to the element that has the given eu.cdevreeze.yaidom.core.Path.Entry (compared to this element as root).
It can be defined as follows:
updateChildElems(Set(pathEntry)) { case (che, pe) => f(che) }
Returns updateChildElemWithNodeSeq(pathEntry) { e => newNodes }
Returns updateChildElemWithNodeSeq(pathEntry) { e => newNodes }
Functionally updates the tree with this element as root element, by applying the passed function to the element that has the given eu.cdevreeze.yaidom.core.Path.Entry (compared to this element as root).
Functionally updates the tree with this element as root element, by applying the passed function to the element that has the given eu.cdevreeze.yaidom.core.Path.Entry (compared to this element as root).
It can be defined as follows:
updateChildElemsWithNodeSeq(Set(pathEntry)) { case (che, pe) => f(che) }
Invokes updateChildElems
, passing the path entries for which the passed function is defined.
Invokes updateChildElems
, passing the path entries for which the passed function is defined. It is equivalent to:
val editsByPathEntries: Map[Path.Entry, ThisElem] = findAllChildElemsWithPathEntries.flatMap({ case (che, pe) => f(che, pe).map(newE => (pe, newE)) }).toMap updateChildElems(editsByPathEntries.keySet) { case (che, pe) => editsByPathEntries.getOrElse(pe, che) }
Updates the child elements with the given path entries, applying the passed update function.
Updates the child elements with the given path entries, applying the passed update function.
That is, returns the equivalent of:
updateChildElemsWithNodeSeq(pathEntries) { case (che, pe) => Vector(f(che, pe)) }
If the set of path entries is small, this method is rather efficient.
Invokes updateChildElemsWithNodeSeq
, passing the path entries for which the passed function is defined.
Invokes updateChildElemsWithNodeSeq
, passing the path entries for which the passed function is defined. It is equivalent to:
val editsByPathEntries: Map[Path.Entry, immutable.IndexedSeq[ThisNode]] = findAllChildElemsWithPathEntries.flatMap({ case (che, pe) => f(che, pe).map(newNodes => (pe, newNodes)) }).toMap updateChildElemsWithNodeSeq(editsByPathEntries.keySet) { case (che, pe) => editsByPathEntries.getOrElse(pe, immutable.IndexedSeq(che)) }
Updates the child elements with the given path entries, applying the passed update function.
Updates the child elements with the given path entries, applying the passed update function. This is the core method of the update API, and the other methods have implementations that directly or indirectly depend on this method.
That is, returns:
if (pathEntries.isEmpty) self else { val indexesByPathEntries: Seq[(Path.Entry, Int)] = collectChildNodeIndexes(pathEntries).toSeq.sortBy(_._2) // Updating in reverse order of indexes, in order not to invalidate the path entries val newChildren = indexesByPathEntries.reverse.foldLeft(self.children) { case (accChildNodes, (pathEntry, idx)) => val che = accChildNodes(idx).asInstanceOf[ThisElem] accChildNodes.patch(idx, f(che, pathEntry), 1) } self.withChildren(newChildren) }
If the set of path entries is small, this method is rather efficient.
Returns updateElemOrSelf(path) { e => newElem }
Returns updateElemOrSelf(path) { e => newElem }
Functionally updates the tree with this element as root element, by applying the passed function to the element that has the given eu.cdevreeze.yaidom.core.Path (compared to this element as root).
Functionally updates the tree with this element as root element, by applying the passed function to the element that has the given eu.cdevreeze.yaidom.core.Path (compared to this element as root).
It can be defined as follows:
updateElemsOrSelf(Set(path)) { case (e, path) => f(e) }
Returns updateElemWithNodeSeq(path) { e => newNodes }
Returns updateElemWithNodeSeq(path) { e => newNodes }
Functionally updates the tree with this element as root element, by applying the passed function to the element that has the given eu.cdevreeze.yaidom.core.Path (compared to this element as root).
Functionally updates the tree with this element as root element, by applying the passed function to the element that has the given eu.cdevreeze.yaidom.core.Path (compared to this element as root). If the given path is the root path, this element itself is returned unchanged.
This function could be defined as follows:
updateElemsWithNodeSeq(Set(path)) { case (e, path) => f(e) }
Updates the descendant elements with the given paths, applying the passed update function.
Updates the descendant elements with the given paths, applying the passed update function.
That is, returns:
val pathsByFirstEntry: Map[Path.Entry, Set[Path]] = paths.filterNot(_.isEmpty).groupBy(_.firstEntry) updateChildElems(pathsByFirstEntry.keySet) { case (che, pathEntry) => che.updateElemsOrSelf(pathsByFirstEntry(pathEntry).map(_.withoutFirstEntry)) { case (elm, path) => f(elm, path.prepend(pathEntry)) } }
If the set of paths is small, this method is rather efficient.
Updates the descendant-or-self elements with the given paths, applying the passed update function.
Updates the descendant-or-self elements with the given paths, applying the passed update function.
That is, returns:
val pathsByFirstEntry: Map[Path.Entry, Set[Path]] = paths.filterNot(_.isEmpty).groupBy(_.firstEntry) val descendantUpdateResult = updateChildElems(pathsByFirstEntry.keySet) { case (che, pathEntry) => // Recursive (but non-tail-recursive) call che.updateElemsOrSelf(pathsByFirstEntry(pathEntry).map(_.withoutFirstEntry)) { case (elm, path) => f(elm, path.prepend(pathEntry)) } } if (paths.contains(Path.Empty)) f(descendantUpdateResult, Path.Empty) else descendantUpdateResult
In other words, returns:
val descendantUpdateResult = updateElems(paths)(f) if (paths.contains(Path.Empty)) f(descendantUpdateResult, Path.Empty) else descendantUpdateResult
If the set of paths is small, this method is rather efficient.
Updates the descendant-or-self elements with the given paths, applying the passed update function.
Updates the descendant-or-self elements with the given paths, applying the passed update function.
That is, returns:
val pathsByFirstEntry: Map[Path.Entry, Set[Path]] = paths.filterNot(_.isEmpty).groupBy(_.firstEntry) val descendantUpdateResult = updateChildElemsWithNodeSeq(pathsByFirstEntry.keySet) { case (che, pathEntry) => // Recursive (but non-tail-recursive) call che.updateElemsOrSelfWithNodeSeq(pathsByFirstEntry(pathEntry).map(_.withoutFirstEntry)) { case (elm, path) => f(elm, path.prepend(pathEntry)) } } if (paths.contains(Path.Empty)) f(descendantUpdateResult, Path.Empty) else Vector(descendantUpdateResult)
In other words, returns:
val descendantUpdateResult = updateElemsWithNodeSeq(paths)(f) if (paths.contains(Path.Empty)) f(descendantUpdateResult, Path.Empty) else Vector(descendantUpdateResult)
If the set of paths is small, this method is rather efficient.
Updates the descendant elements with the given paths, applying the passed update function.
Updates the descendant elements with the given paths, applying the passed update function.
That is, returns:
val pathsByFirstEntry: Map[Path.Entry, Set[Path]] = paths.filterNot(_.isEmpty).groupBy(_.firstEntry) updateChildElemsWithNodeSeq(pathsByFirstEntry.keySet) { case (che, pathEntry) => che.updateElemsOrSelfWithNodeSeq(pathsByFirstEntry(pathEntry).map(_.withoutFirstEntry)) { case (elm, path) => f(elm, path.prepend(pathEntry)) } }
If the set of paths is small, this method is rather efficient.
Invokes updateElems
, passing the topmost non-empty paths for which the passed function is defined.
Invokes updateElems
, passing the topmost non-empty paths for which the passed function is defined. It is equivalent to:
val mutableEditsByPaths = mutable.Map[Path, ThisElem]() val foundElems = ElemWithPath(self) findTopmostElems { elm => val optResult = f(elm.elem, elm.path) if (optResult.isDefined) { mutableEditsByPaths += (elm.path -> optResult.get) } optResult.isDefined } val editsByPaths = mutableEditsByPaths.toMap updateElems(editsByPaths.keySet) { case (elm, path) => editsByPaths.getOrElse(path, elm) }
Invokes updateElemsOrSelf
, passing the topmost paths for which the passed function is defined.
Invokes updateElemsOrSelf
, passing the topmost paths for which the passed function is defined. It is equivalent to:
val mutableEditsByPaths = mutable.Map[Path, ThisElem]() val foundElems = ElemWithPath(self) findTopmostElemsOrSelf { elm => val optResult = f(elm.elem, elm.path) if (optResult.isDefined) { mutableEditsByPaths += (elm.path -> optResult.get) } optResult.isDefined } val editsByPaths = mutableEditsByPaths.toMap updateElemsOrSelf(editsByPaths.keySet) { case (elm, path) => editsByPaths.getOrElse(path, elm) }
Invokes updateElemsOrSelfWithNodeSeq
, passing the topmost paths for which the passed function is defined.
Invokes updateElemsOrSelfWithNodeSeq
, passing the topmost paths for which the passed function is defined. It is equivalent to:
val mutableEditsByPaths = mutable.Map[Path, immutable.IndexedSeq[ThisNode]]() val foundElems = ElemWithPath(self) findTopmostElemsOrSelf { elm => val optResult = f(elm.elem, elm.path) if (optResult.isDefined) { mutableEditsByPaths += (elm.path -> optResult.get) } optResult.isDefined } val editsByPaths = mutableEditsByPaths.toMap updateElemsOrSelfWithNodeSeq(editsByPaths.keySet) { case (elm, path) => editsByPaths.getOrElse(path, immutable.IndexedSeq(elm)) }
Invokes updateElemsWithNodeSeq
, passing the topmost non-empty paths for which the passed function is defined.
Invokes updateElemsWithNodeSeq
, passing the topmost non-empty paths for which the passed function is defined. It is equivalent to:
val mutableEditsByPaths = mutable.Map[Path, immutable.IndexedSeq[ThisNode]]() val foundElems = ElemWithPath(self) findTopmostElems { elm => val optResult = f(elm.elem, elm.path) if (optResult.isDefined) { mutableEditsByPaths += (elm.path -> optResult.get) } optResult.isDefined } val editsByPaths = mutableEditsByPaths.toMap updateElemsWithNodeSeq(editsByPaths.keySet) { case (elm, path) => editsByPaths.getOrElse(path, immutable.IndexedSeq(elm)) }
Shorthand for withChildren(newChildSeqs.flatten)
Shorthand for withChildren(newChildSeqs.flatten)
Creates a copy, but with (only) the children passed as parameter newChildren
Creates a copy, but with (only) the children passed as parameter newChildren
Shorthand for withChildren(children.patch(from, newChildren, replace))
Shorthand for withChildren(children.patch(from, newChildren, replace))
Shorthand for withChildren(children.updated(index, newChild))
Shorthand for withChildren(children.updated(index, newChild))
Element as abstract data type. It contains only expanded names, not qualified names. This reminds of James Clark notation for XML trees and expanded names, where qualified names are absent.
See the documentation of the mixed-in query API trait(s) for more details on the uniform query API offered by this class.
Namespace declarations (and undeclarations) are not considered attributes in this API, just like in the rest of yaidom.
To illustrate equality comparisons in action, consider the following example yaidom
Elem
, namedschemaElem1
:Now consider the following equivalent yaidom
Elem
, namedschemaElem2
, differing only in namespace prefixes, and in indentation:These 2 XML trees can be considered equal, if we take indentation and namespace prefixes out of the equation. Note that namespace prefixes also occur in the "type" attributes! The following equality comparison returns true: