[use case] Performs a shallow-select on the XML tree according to the specified selector function.
Performs a shallow-select on the XML tree according to the specified selector function. Shallow selection is defined according to the following expression:
Performs a shallow-select on the XML tree according to the specified selector function.
Performs a shallow-select on the XML tree according to the specified selector function. Shallow selection is defined according to the following expression:
nodes flatMap {
case Elem(_, _, children) => children collect selector
case _ => Group()
}
In English, this means that a shallow selection works by first selecting only the Elem(s) at the top level and then filtering their children according to the selector. The results of these filtrations are concatenated together, producing a single flattened result.
Very important: This is not the same as the XPath / operator!
(nor does it strive to be) XPath is inconsistent in its selection semantics,
varying them slightly depending on whether or not you are selecting from
the top level or in the middle of a compound expression. As a result, it
is categorically impossible to implement XPath in a combinatorial
fashion. Rather than give up on combinators, we chose to give up on XPath.
In practice, this "select child Elem(s), then filter their children" behavior
tends to be the most useful variant of the XPath selection. The "missed"
case here is applying a filter to the top-level set of nodes. This is
currently not handled by the API (perhaps in future). For now, if you need
this functionality, it's pretty easy to get it using the filter method.
The results of this function will be a collection of some variety, but the exact type is determined by the selector itself. For example:
val ns: Group[Node] = ... ns \ "name" ns \ * ns \ text
The three selection expressions here produce very different results. The
first will produce a collection of type Zipper[Elem],
the second will produce Zipper[Node],
while the third will produce scala.collection.Traversable[scala.String].
This reflects the fact that the selector produced (by implicit conversion)
from a String will only filter for nodes of type Elem.
However, the * selector will filter for all nodes (as the wildcard
symbol would suggest) and thus it must return a collection containing the
fully-generic Node. Finally, the text selector
specifically pulls out the textual contents of nodes, and thus its results
will not be nodes at all, but raw String(s).
Whenever supported by the resulting collection type, the selection operation will preserve a "backtrace", or an "undo log" of sorts. This backtrace is known as a zipper context. This context makes it possible to operate on the collection resulting from performing a selection, then unselect to rebuild the original collection around it (modulo the changes made). This provides a very clean and powerful way of drilling down into an XML tree, making some changes and then realizing those changes within the context of the full tree. In a sense, it solves the major inconvenience associated with immutable tree structures: the need to manually rebuild the entire ancestry of the tree after making a change somewhere within.
[use case] Performs a deep-select on the XML tree according to the specified selector function.
Performs a deep-select on the XML tree according to the specified selector function. Deep selection is defined according to the following recursion:
Performs a deep-select on the XML tree according to the specified selector function.
Performs a deep-select on the XML tree according to the specified selector function. Deep selection is defined according to the following recursion:
def deep(g: Group[Node]):That =
g flatMap {n => Group(n).collect(selector) ++ deep(n.children)}
nodes flatMap {n => deep(n.children)}
In English, this means that deep selection is defined simply as a depth-first search through the tree, all the way from the root down to the leaves. Note that the recursion does not short circuit when a result is found. Thus, if a parent node matches the selector as well as one of its children, then both the parent and the child will be returned, with the parent preceeding the child in the results.
Just as with shallow selection, the very outermost level of the group is not
considered in the selection. Thus, deep selection is not exactly the
same as the XPath // operator, since // will consider the outermost level,
while Anti-XML's deep selection \\ will not.
[use case] Performs a short-circuiting deep-select on the XML tree according to the specified selector.
Performs a short-circuiting deep-select on the XML tree according to the specified selector. Short-circuit deep selection is defined according to the following recursion:
Performs a short-circuiting deep-select on the XML tree according to the specified selector.
Performs a short-circuiting deep-select on the XML tree according to the specified selector. Short-circuit deep selection is defined according to the following recursion:
def deep(g: Group[Node]):That =
g flatMap {n =>
if (selector.isDefinedAt(n)) Group(n).collect(selector)
else deep(n.children)
}
nodes flatMap {n => deep(n.children)}
Like \\, this performs a depth-first search through the tree. However, any time
the selector matches a node, it's children are skipped over rather than being searched.
Thus, the result is guaranteed to never contain both a node and one of its descendants.
Just as with shallow selection, the very outermost level of the group is not considered in the selection.
[use case] Performs a selection on the top-level nodes of this group.
Performs a selection on the top-level nodes of this group. The nodes returned by this method are exactly the same as the nodes returned by:
Performs a selection on the top-level nodes of this group.
Performs a selection on the top-level nodes of this group. The nodes returned by this method are exactly the same as the nodes returned by:
nodes.collect(selector)
However, this method differs from collect in that it can return a Zipper
with full unselect functionality. Thus, it is possible to select a subset of a group,
operate on that subset, and then call unselect to pull those operations back to the original group.