0
votes

I'm new to Marklogic XSLT transformations and I have the below questions.

What XSLT engine does Marklogic use to transform document using xdmp:xslt-invoke() function?Is there a way that we can support XSLT 3.0 version in Marklogic?

I'm trying to use XSLT 3.0 version that has the below variable for transformation

<xsl:variable name="format-map" as="map(xs:string,xs:string)">

and I'm getting below error when using xdmp:xslt-invoke() function in Marklogic

XSLT-BADSEQTYPE: (err:XTSE0020) /*:stylesheet/*:variable[1] -- Invalid sequence type: /*:stylesheet/*:variable[1]/@as (XDMP-UNEXPECTED: (err:XPST0003) Unexpected token syntax error, unexpected Lpar_, expecting $end)

Please let me know how to resolve this

1
According to the docs at docs.marklogic.com/guide/xquery/xslt they support XSLT 2.0, not 3.0. The seem to allow using their own extensions to the W3C XDM data model in XQuery and XSLT, in XSLT by using e.g. xdmp:dialect="1.0-ml" on the root element of the stylesheet, that way you might be able to use the map extension they provide, which is not the one specified by the W3C, however. - Martin Honnen
@MartinHonnen I tried the your suggestion by declaring xdmp:dialect="1.0-ml" in the stylesheet but still getting the same error. - Antony
As I said, their syntax and type system for maps is not the one the W3C specified so I don't think the as="map(xs:string,xs:string)" is going to work, it is more like <xsl:variable name="map" select="map:new() => map:with('foo', 'bar')"/> and then you can use <xsl:value-of select="map:get($map, 'foo')"/>. And I think you need to declare xmlns:map="http://marklogic.com/xdmp/map". I don't have access to Marklogic currently so you might want to experiment on your own or wait until you get an answer from someone with more insight. - Martin Honnen

1 Answers

2
votes

MarkLogic supports XSLT 2.0, but that doesn't stop you from using in-memory style maps.

Just declare the MarkLogic map namespace in the stylesheet, then you've got access to MarkLogic's map functions. Just watch out for 1 key difference which is that MarkLogic's maps are mutable, where as maps in XSLT 3.0 are immutable.

In other words, if you add/change/delete content to a MarkLogic map, with say map:put($map, "a", "b"), the map $map is changed directly, in-place - and when you try to do map:get($map, "a") later, you'll get the most recent version of what a is, i.e. "b".

If you try to update a map in XSLT 3.0, you'll get a whole new updated immutable copy.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:map="http://marklogic.com/xdmp/map"
  exclude-result-prefixes="map"                                                                                                                                                                         
  version="2.0">

  <xsl:variable name="my-map" as="map:map" select="map:map()" />

  <xsl:template match="/">
    <xsl:sequence select="map:put($my-map, 'a', 'b')"/>
    <xsl:value-of select="map:get($my-map, 'a')"/>
  </xsl:template>

</xsl:stylesheet>