I want to take a sequence of maps and find distinct values, the obvious thing to do is.
<xsl:variable name="sequence" select="
( map { 'foo' : 1, 'bar' : () },
map { 'foo' : 1, 'bar' : '3' },
map { 'foo' : 1, 'bar' : '3' } )" as="map(xs:string,item()*)*"/>
<xsl:variable name="distinct" select="distinct-values($sequence)"/>
but this raises the warning
Error in xsl:variable/@select on line 29 column 76 of PurchasableSeasonOG.content.xsl: FOTY0013 An atomic value is required for the first argument of fn:distinct-values(), but the supplied type is a map type, which cannot be atomized
i.e. maps aren't atomic values, fair enough.
I'm expecting the answer to be
( map { 'foo' : 1, 'bar' : () },
map { 'foo' : 1, 'bar' : '3' } )
but how would you do this?
P.S.
I can see how to do this with hard coded for-each-group, or even construct a recursive function to do this via for-each-group, though I'm hoping there is something in the XPath toolbox to do it, and I'm struggling to group by a key that can be an empty sequence.
deep-equal
works on maps so one way would be
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all">
<xsl:variable name="sequence" select="
( map { 'foo' : 1, 'bar' : () },
map { 'foo' : 1, 'bar' : '3' },
map { 'foo' : 1, 'bar' : '3' } )" as="map(xs:string,item()*)*"/>
<xsl:output method="adaptive"/>
<xsl:template match="/" name="xsl:initial-template">
<xsl:sequence
select="fold-left($sequence, (), function($a, $m) { $a, $m[not(some $m2 in $a satisfies deep-equal($m, $m2))] })"/>
</xsl:template>
</xsl:stylesheet>