MrD at KookerellaLtd
MrD at KookerellaLtd

Reputation: 2807

getting distinct values from a sequence of maps

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.

Upvotes: 0

Views: 35

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167716

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>

Example fiddle.

Upvotes: 0

Related Questions