Open michaelhkay opened 5 months ago
Note also the above proposes a change to the handling of any (XML) nodes found in the map/array structure. Currently these are processed as if by the on-no-match="shallow-copy" rule. The proposal changes this to move the nodes directly into the output structure without copying. Of course this can be modified by adding an explicit template rule that matches nodes; but moving them unchanged seems the right default.
This means it may be better to find a different name for this action. Not easy to find something that adequately summarises the behaviour. Perhaps on-no-match="traverse".
I also propose that we change the default for the select attribute of xsl:apply-templates
. The current default of child::node()
makes no sense when processing maps and arrays; and since in 3.0 using the default will always give an error when the context item is a map or array, I think we can safely change it.
The default when the context item is a map or array should be to use the select expressions that appear in the match="map(*)"
and match="array(*)
template rules shown above.
I support this improvement. Is there some way we can abbreviate record(map-entry-item as ..., key as ..., value as ..., item as item(), position as ...)
and its array counterpart to a reserved keyword (or the like), so we do not have to memorize this record type when writing templates for the contents of the map/array?
The work on deep lookup with modifiers enables an improved set of rules for processing trees of maps and arrays using a mode with
on-no-match="shallow-copy-all"
.Recall that the intent is that if the user writes no template rules at all in such a mode, the effect is to recursively copy the entire structure without change. But it should be as easy as possible for the user to add template rules to override this processing for a selected part of the structure.
With this in mind, the proposed built-in rules are as follows:
For an array with no additional information available, we split it up into array members in a way that makes it possible to override the processing for a specific array member:
The field 'array-member' here is a dummy, provided simply to make it easier to match these records at the next level of processing.
For the array members, when represented in this way, the items in the array member are processed one-by-one to produce a new array member:
The new array members are delivered as singleton maps, in the form expected by the match="array(*)" template given above.
For the individual items within each array member, the default is simply to apply-templates to the item:
Similarly for a map with no additional information, we reconstruct the map by applying templates to its individual entries:
The built in processing for a map entry represented in this way is to reconstruct the map entry by applying templates to its individual items:
For the individual items within each map entry, the default is simply to apply-templates to the item:
And of course the fallback processing for items not in the above list is to return them unchanged:
This allows user-written template rules to intervene at any of these levels, and to have access to contextual information about the item they are processing. For example to rename map entries with key "comment" to have key "note" instead, use:
There's one more refinement I would like, which is to provide access to the selection path for each map and array entry. I think this can be done by ensuring that within the template, items are labeled so that the function call selection-path(?value) or selection-path(?item) delivers the required result.