Subject: Re: [xsl] Techniques for Sorting and Reducing Maps in XSLT 3/XPath 3? From: "Michael Kay mike@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Thu, 19 Jul 2018 13:19:33 -0000 |
Looks good. Don't forget that map:get(., 'version') can be written ?version and > $courses-for-locale ! > (if (map:get(., 'version') eq $highest-version) > then . > else () can be written $courses-for-locale[?version eq $highest-version] Michael Kay Saxonica > On 19 Jul 2018, at 13:16, Eliot Kimber ekimber@xxxxxxxxxxxx <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote: > > Here is my current solution, which is definitely an improvement over my earlier solution. I hadnbt realized (or it didnbt occur to me) that I could use for-each-group on maps. Using for-each-group and grouping by a specific field is certainly easy and straightforward: > > For this data, the paths provide the course details, in particular, course ID and locale. I also have to eliminate config.xml files that are not the ones Ibm looking for, which I do just by counting the number of tokens in the path. > > <xsl:variable name="candidate-configs" as="map(*)*" > select="collection($courses-dir || '?recurse=yes;metadata=yes;match=config.xml')" > /> > > <!-- Select configurations that are in the appropriate locale and that > are course configurations and not course content configurations (config.xml > is used both for course description and within the course content directory). > > Result is a sequence of maps, one for each selected candidate course. > --> > <xsl:variable name="configs-to-use" as="map(*)*"> > <xsl:for-each select="$candidate-configs"> > <xsl:variable name="cand" as="map(*)" select="."/> > <xsl:variable name="path-base" as="xs:string" select="$cand?name"/> > <xsl:variable name="path" as="xs:string" select="substring-after($path-base, $courses-dir || '/')"/> > <xsl:variable name="tokens" as="xs:string*" select="tokenize($path, '/')"/> > <xsl:variable name="course-group" as="xs:string" select="$tokens[1]"/> > <xsl:variable name="course-id" as="xs:string" select="$tokens[2]"/> > <xsl:variable name="locale" as="xs:string" select="$tokens[3]"/> > <xsl:variable name="version" as="xs:string" select="$tokens[4]"/> > <xsl:variable name="new-map" as="map(*)" > select=" > map{ > 'course-group' : $course-group, > 'course-id' : $course-id, > 'locale' : $locale, > 'version' : $version, > 'course-key' : ($course-group, $course-id) => string-join('^'), > 'course-key-locale' : ($course-group, $course-id, $locale) => string-join('^') > }" > /> > <xsl:if test="(empty($locales) or (exists($locales) and $locale = $locales)) and count($tokens) eq 6"> > <xsl:sequence select="map:merge((., $new-map))"/> > </xsl:if> > </xsl:for-each> > </xsl:variable> > > <!-- Now group by course ID and locale in order to select the highest version of each course. --> > <xsl:variable name="course-configs-by-course-key-locale" as="map(xs:string, map(*))"> > <xsl:map> > <xsl:for-each-group select="$configs-to-use" group-by=".?course-key-locale"> > <xsl:variable name="courses-for-locale" as="map(*)*" select="current-group()"/> > <xsl:variable name="highest-version" as="xs:string" > select="$courses-for-locale ! map:get(., 'version') ! xs:double(.) => max() => format-number('#.0')" > /> > <xsl:variable name="course-map" as="map(*)*" > select=" > $courses-for-locale ! > (if (map:get(., 'version') eq $highest-version) > then . > else () > )" > /> > <xsl:sequence select="map:entry(current-grouping-key(), $course-map)"/> > </xsl:for-each-group> > </xsl:map> > </xsl:variable> > > Cheers, > > E. > -- > Eliot Kimber > http://contrext.com <http://contrext.com/> > > > > From: "Mukul Gandhi gandhi.mukul@xxxxxxxxx <mailto:gandhi.mukul@xxxxxxxxx>" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx <mailto:xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>> > Reply-To: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx <mailto:xsl-list@xxxxxxxxxxxxxxxxxxxxxx>> > Date: Saturday, July 7, 2018 at 2:01 AM > To: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx <mailto:xsl-list@xxxxxxxxxxxxxxxxxxxxxx>> > Subject: Re: [xsl] Techniques for Sorting and Reducing Maps in XSLT 3/XPath 3? > > On Fri, Jul 6, 2018 at 9:58 PM, Liam R. E. Quin liam@xxxxxx <mailto:liam@xxxxxx> <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx <mailto:xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>> wrote: >> On your xsl:iterate question, i'd generally try for-each and/or for- >> each-group before xsl:iterate. The reason is largely that i think it >> encourage thinking in terms of a functional mapping rather than an >> imperative loop, and that can help clarity of thought. > > I'm still not up to speed with using XSLT 3.0 (but I'm trying to). But I agree with your point Liam. > > > > > -- > Regards, > Mukul Gandhi > XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list> > EasyUnsubscribe <x-msg://101/-list/1278982> (by email <applewebdata://09520B08-E59F-4D3A-AE57-ACF7B6C75260>) > XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list> > EasyUnsubscribe <-list/293509> (by email <>)
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Techniques for Sorting an, Eliot Kimber ekimber | Thread | [xsl] [ANN] Balisage 2018 Program u, Tommie Usdin btusdin |
Re: [xsl] Techniques for Sorting an, Eliot Kimber ekimber | Date | [xsl] Fwd: Your posting to XSL-List, VISHNU SINGH svishnu |
Month |