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.
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.
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(elem, e => transformElemsOrSelf(e, 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(elem, e => transformElemsOrSelf(e, f)))
In other words, returns the equivalent of:
f(transformElems(elem, 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(elem, e => transformElemsOrSelfToNodeSeq(e, f)))
In other words, returns the equivalent of:
f(transformElemsToNodeSeq(elem, 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(elem, e => transformElemsOrSelfToNodeSeq(e, f))
It is equivalent to the following expression:
transformElemsOrSelf(elem, { e => transformChildElemsToNodeSeq(e, f) })
This is the element transformation API, as function API instead of OO API. That is, this is the function API corresponding to trait eu.cdevreeze.yaidom.queryapi.TransformableElemApi.
See trait
TransformableElemApi
for more info about element transformations in yaidom, and their properties.This functional API is more widely applicable than trait
TransformableElemApi
. First, it can be implemented for arbitrary element types, even non-yaidom ones. Second, implementations can easily carry state that is shared by update functions, such as a SaxonProcessor
in the case of a Saxon implementation of this API.When using this API for elements that carry context such as "ancestry state", be careful when writing transformation functions that are passed to the functions of this API. For example, if the element type is
BackingElemApi
or a sub-type, such sensitive state includes the base URI, document URI, thePath
relative to the root element, and most important of all, the root element itself. It is up to the user of the API to keep such state consistent during transformations, and to be careful when depending on state that is volatile during transformations.Also note for
BackingElemApi
elements, if a transformation function alters "ancestry state" such as (base and document) URIs, paths etc., these altered values may be ignored, depending on the API calls made.ElemTransformationApi more formally
In order to get started using the API, this more formal section can safely be skipped. On the other hand, this section may provide a deeper understanding of the API.
Some provable properties hold about this
ElemTransformationApi
API in terms of the more low levelElemUpdateApi
API.Let's first try to define the methods of
ElemTransformationApi
in terms of theElemUpdateApi
API. Below their equivalence will be proven. We define the following, assuming typeElem
to be a yaidom "indexed element" type:1. Property about transformChildElems in terms of transformChildElems2
The following property must hold, for all elements and (pure) element transformation functions:
No proof is provided, but this property must obviously hold, since
transformChildElems
replaces child element nodes by applying the given function, and leaves the other child nodes alone, and methodtransformChildElems2
does the same. The latter function does it via child path entries (translated to child node indexes), iterating over child nodes in reverse order (in order not to invalidate the next processed path entry), but the net effect is the same.2. Property about transformElemsOrSelf in terms of transformElemsOrSelf2
The following property holds, for all elements and (pure) element transformation functions:
Below follows a proof of this property by structural induction.
Base case
If
elem
has no child elements, then the LHS can be rewritten as follows:which is the RHS.
Inductive step
If
elem
does have child elements, the LHS can be rewritten as:which is the RHS.
This completes the proof. For the other
ElemTransformationApi
methods, analogous provable properties hold.