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
TransformableElemApifor 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 SaxonProcessorin 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
BackingElemApior a sub-type, such sensitive state includes the base URI, document URI, thePathrelative 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
BackingElemApielements, 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
ElemTransformationApiAPI in terms of the more low levelElemUpdateApiAPI.Let's first try to define the methods of
ElemTransformationApiin terms of theElemUpdateApiAPI. Below their equivalence will be proven. We define the following, assuming typeElemTypeto 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
transformChildElemsreplaces child element nodes by applying the given function, and leaves the other child nodes alone, and methodtransformChildElems2does 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
elemhas no child elements, then the LHS can be rewritten as follows:which is the RHS.
Inductive step
If
elemdoes have child elements, the LHS can be rewritten as:which is the RHS.
This completes the proof. For the other
ElemTransformationApimethods, analogous provable properties hold.