- From: Martin Honnen <martin.honnen@gmx.de>
- Date: Mon, 17 Oct 2022 22:39:26 +0200
- To: Michael Kay <mike@saxonica.com>
- Cc: public-xslt-40@w3.org
On 10/17/2022 6:11 PM, Michael Kay wrote: > It's probably best to put comments against the relevant Git issue. We're trying - with limited success - to keep discussions on different topics separate. > > Yes, I did see it, and I see pro's and con's in the idea so I'm sitting on the fence. > > (a) Dimitre is pushing for maps to be generalised so a key is a sequence of atomic values (or beyond...), and that's a different semantics for allowing map:build to compute multiple keys each of which is atomic. I remembered that but as it didn't appear to have a resolution I tried to consider the suggestions for map:group-by or now map:build based on the existing map model and see whether they could be improved/generalized. > (b) The current draft of map:build envisages a call to $key() to compute the key, and a call to $value() to compute the corresponding value. If there were multiple keys, would they all map to the same value? Or would you want to generate multiple key-value pairs from a single item in the input sequence? Which would suggest a single callback producing a composite result; but that starts to feel more like the existing map:merge. > My idea and understanding and suggestion is based on the implementation I included below which computes the same value based on the $value function parameter and the item in the sequence as the original suggestion in your pull request. It only uses fold-left on the possible key sequence, with the map as the accumulator, to recursively add any key/value pair to the map. It tries to allow to map an item to possibly more than one group, which I hoped the example and the implementation (and for the XSLT guys, the reference to the sample from the XSLT spec) would make clear. In my view it is just a refinement to justify the statement behind the original map:group-by, namely that "This function may sometimes be an effective substitute for the xsl:for-each-group instruction in XSLT.". Admittedly that statement doesn't appear any longer for map:build but I continue to think that there is a use case (from that origin) to allow for a key sequence, easily implemented as suggested below. > >>> When map:group-by was introduced I found the restriction of a single key >>> instead of a sequence of keys unnecessarily restrictive (some people on >>> Slack agreed), the same appears in my view to be the case for the new >>> map:build, I think it could be easily adapted to handle a sequence of >>> keys by using e.g. >>> >>> fold-left($input, map{}, ->($map, $next) { >>> >>> fold-left($key($next), $map, ->($map, $key) { >>> let $nextValue := $value($next) return >>> if (map:contains($map, $key)) >>> then map:put($map, $key, $combine($map($key), $nextValue)) >>> else map:put($map, $key, $nextValue)}) >>> } >>> ) >>> >>> as the implementation body/definition of the result of >>> >>> map:build( >>> $input as item()*, >>> $key as function(item()) as xs:anyAtomicType* := fn:identity#1, >>> $value as function(item()) as item()* := fn:identity#1, >>> $combine as function(item()*, item()*) as item()* := fn:op(',') >>> ) as map(*) >>> >>> >>> Use case in my view is the classical example of the XSLT 3 spec where in >>> e.g. >>> >>> <titles> >>> <title>A Beginner's Guide to <ix>Java</ix></title> >>> <title>Learning <ix>XML</ix></title> >>> <title>Using <ix>XML</ix> with <ix>Java</ix></title> >>> </titles> >>> >>> you want to group the "title" elements by the "ix" child elements, with >>> the proposed change above that would give e.g. >>> >>> map { >>> "Java": (<title>A Beginner's Guide to <ix>Java</ix> >>> </title>, <title>Using <ix>XML</ix> with <ix>Java</ix> >>> </title>), >>> "XML": (<title>Learning <ix>XML</ix> >>> </title>, <title>Using <ix>XML</ix> with <ix>Java</ix> >>> </title>) >>> } >>> >>> >>> XSLT 2/3 grouping always had this feature to allow an item in the >>> grouping population to belong to several groups, the above change would >>> give that same power to XPath/XQuery based grouping using map:build. >>> >>> >>> >>> >>> >>> >>> >
Received on Monday, 17 October 2022 20:39:40 UTC