Re: [xsl] Constructing a Map Using xsl:for-each-group

Subject: Re: [xsl] Constructing a Map Using xsl:for-each-group
From: "Eliot Kimber ekimber@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 25 May 2018 23:37:59 -0000
Doh!

Can I blame illness?

I replaced the for-each-group with this:

  <xsl:variable name="unique-target-ids" as="xs:string*"
        select="$docbook-links/@linkend ! string(.) => distinct-values()"
      />
      <xsl:variable name="links-by-target-id" as="map(xs:string,
element()*)*"
        select="
        (
          for $key in $unique-target-ids
          return
            let $links := key('links-by-linkend', $key, $docbook-doc)
            return if (exists($links)) then map:entry($key, $links) else ()
        ) =>
        map:merge()"
        />

Which works and starts to feel very XQueryish, which I guess is unavoidable
now that I can use let in XPath expressions.

Cheers,

E.

--
Eliot Kimber
http://contrext.com


o;?On 5/25/18, 6:21 PM, "Michael Kay mike@xxxxxxxxxxxx"
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:

    Your <map:entry> elements should be <xsl:map-entry>.

    Had me baffled for a bit.

    Michael Kay
    Saxonica

    > On 26 May 2018, at 00:06, Eliot Kimber ekimber@xxxxxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
    >
    > I want to construct a map where the keys are attribute values and the
entries contain the elements that exhibit those attribute values. The obvious
way to do this is with for-each-group:
    >
    >      <xsl:variable name="links-by-target-id" as="map(xs:string,
element()*)">
    >        <xsl:map>
    >          <xsl:for-each-group select="$docbook-links"
group-by="@linkend">
    >            <map:entry key="{current-grouping-key()}">
    >              <xsl:sequence select="current-group()"/>
    >            </map:entry>
    >          </xsl:for-each-group>
    >        </xsl:map>
    >      </xsl:variable>
    >
    > However, using Saxon 9.8.0.8 from Oxygen I get this message:
    >
    > "Required item type of xsl:map sequence constructor is map(*); supplied
value (xsl:for-each-group) has item type element(). The expression can succeed
only if the supplied value is an empty sequence."
    >
    > The XSLT spec says that the contents of <xsl:map> is a sequence
constructor, which for-each-group certainly is.
    >
    > Is this message legit? I don't see how it can be but maybe I'm missing a
subtlety in the map instruction?
    >
    > Thanks,
    >
    > Eliot
    > --
    > Eliot Kimber
    > http://contrext.com

Current Thread