Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is it possible to embed function (that constructs an element) by value (i.e. anonymous functions/lambdas)

Is it possible to embed a function inside a map (for example) by value e.g.

<xsl:function name="kooks:stringAdd" as="xs:string">
    <xsl:param name="s1" as="xs:string"/>
    <xsl:param name="s2" as="xs:string"/>
    <xsl:sequence select="concat($s1,$s2)"/>
</xsl:function>

<xsl:variable name="stringMonoid" as="map(*)">
    <xsl:map>
        <xsl:map-entry key="'zero'" select="''" as="xs:string"/>
        <xsl:map-entry key="'add'" select="kooks:stringAdd#2"/>
    </xsl:map>
</xsl:variable>

can i write it (in psuedo xslt) like this.

<xsl:variable name="stringMonoid" as="map(*)">
    <xsl:map>
        <xsl:map-entry key="'zero'" select="''" as="xs:string"/>
        <xsl:map-entry key="'add'">
            <xsl:function as="xs:string">
                <xsl:param name="s1" as="xs:string"/>
                <xsl:param name="s2" as="xs:string"/>
                <xsl:sequence select="concat($s1,$s2)"/>
            </xsl:function>
        </xsl:map>
    </xsl:map>
</xsl:variable>

Clarification, the question is about XSLT functions, I want to be able to construct and return elements (sadly the example returns atomic types), and whilst you can embed xpath expressions that contain inline functions, I’m not sure these can construct elements.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You can use an anonymous function/lambda expression as a key value e.g.

<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"
  expand-text="yes">

  <xsl:output method="xml" indent="yes"/>
  
  <xsl:variable name="stringMonoid" as="map(*)"
    select="map {
             'zero' : '',
             'add' : function($s1 as xs:string, $s2 as xs:string) { $s1 || $s2 }
           }"/>

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:template match="/" name="xsl:initial-template">
    <test>{$stringMonoid?add('This is a ', 'test')}</test>
    <xsl:comment xmlns:saxon="http://saxon.sf.net/">Run with {system-property('xsl:product-name')} {system-property('xsl:product-version')} at {current-dateTime()}</xsl:comment>
  </xsl:template>

</xsl:stylesheet>

outputs something like (the processor and date info will vary)

<?xml version="1.0" encoding="UTF-8"?>
<test>This is a test</test>
<!--Run with SAXON HE 10.6 at 2023-10-12T12:13:27.373+02:00-->

Example fiddle using SaxonC HE 12.3.

If you want to create the map with xsl:map then

  <xsl:variable name="stringMonoid" as="map(*)">
    <xsl:map>
      <xsl:map-entry key="'zero'" select="''"/>
      <xsl:map-entry key="'add'" select="function($s1 as xs:string, $s2 as xs:string) { $s1 || $s2 }"/>
    </xsl:map>
  </xsl:variable>

is possible for an anonymous function (created with XPath, admittedly). But it is not clear to me why you would want to use XSLT to create an anonymous function, if your first example has a named function defined with xsl:function, why doesn’t that suffice?

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading