Note that the optional options argument in map:merge can change the way it handles duplicate keys. I’ve used this to create maps of normalized document ids from two different collections to de-dup, Where the ids SHOULD be uniq within a collection, but actually aren’t, or are missing.
https://www.w3.org/TR/xpath-functions-31/#func-map-merge https://www.w3.org/TR/xpath-functions-31/#func-map-merge
( Next step was to split the uniq and non-uniq ones to handle separately. )
declare variable $OAI := map:merge( for $d in $ORG_OAI return map:entry( local:normalize( local:unitid($d )), $d ), map{'duplicates':'combine'}); declare variable $VH := map:merge( for $d in $ORG_VH return map:entry( local:normalize( local:unitid($d )), $d ), map{'duplicates':'combine'});
However, after discussion on this list about SQL join equivalents, I discovered I could do something almost equivalent with a for/join, and that full text search tokenization gives me a similar way of normalizing IDs:
for $VH in collection( $R($ORG)('vh'))/ead/archdesc/did/unitid, $OAI in collection( $R($ORG)('oai'))/ead/archdesc/did/unitid[ . contains text {string($VH)}] order by $VH
I think the map version may be a bit faster, but I haven’t actually measured And they are doing things a bit differently, as I’m not removing the internal duplicates, But using the order by to group multiple matches together to make it visible in the report.
I would also note that dealing with messy data, often with hidden encoding errors in documents, Is the reason I was asking in a previous thread about using the result of one script as context for other queries. Sometimes this ends up being a rather exploratory process, so that has come in very handy.
— Steve M.
On May 25, 2022, at 12:13 PM, Hans-Juergen Rennau hrennau@yahoo.de wrote:
Hi Markus,
although I do not quite understand your description (why should I care for the representation of the map I construct?), it may be that one piece of information is useful to you, as it is not obvious from the spec: it's about how to construct a map dynamically, that is,
(1) when the keys are not known beforehand, (2) and/or when the entry values are assigned in "iterations" of a FLWOR expression
(Especially (2) might be what puzzles you.)
(1) and (2) can't be accomplished when using the map constructor expression, like this: basex "map{'x':1, 'y': false()}"
The trick consists of using a combination of the functions map:merge() [1] and map:entry() [2].
So summarize, the code constructing the map entries is the argument of function map:merge().This code may for example be (most often is) a FLWOR expression. In this code, each entry is constructed by a call of function map:entry(). For a tiny example see below.
Kind regards, Hans-Jürgen
PS: Tiny example demonstrating the construction of maps via map:merge() & map:entry().
(: Creates a map with one entry for each element name encountered in the input document. The entry value is the number of elements with that name. As the map keys are not known in advance, map:merge() is used. :) map:merge( for $elem in //* group by $name := $elem/local-name(.) return map:entry($name, count($elem)) )
[1] https://www.w3.org/TR/xpath-functions-31/#func-map-merge https://www.w3.org/TR/xpath-functions-31/#func-map-merge [2] https://www.w3.org/TR/xpath-functions-31/#func-map-entry https://www.w3.org/TR/xpath-functions-31/#func-map-entry
Am Mittwoch, 25. Mai 2022, 16:59:48 MESZ hat Markus Elfring markus.elfring@web.de Folgendes geschrieben:
Hello,
I would like to construct a map structure based on a dynamic selection by the means of a FLWOR expression. https://www.w3.org/TR/2017/REC-xquery-31-20170321/#id-maps https://www.w3.org/TR/2017/REC-xquery-31-20170321/#id-maps
The keys and associated values should be presented as a CSV-like file by a subsequent data processing step.
Can it become easier to find existing XQuery script examples for such an use case?
Regards, Markus