Project

Profile

Help

Bug #5855 » mapmerge.xsl

Stylesheet - Mary Holstege, 2023-01-25 21:20

 
<?xml version="1.0" encoding="UTF-8"?>
<!--
: Basic testing of functions in utilities library.
:-->
<xsl:stylesheet xmlns:this="http://mathling.com/tests/utilities"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:err="http://www.w3.org/2005/xqt-errors"
xmlns:ixsl="http://saxonica.com/ns/interactiveXSLT"
extension-element-prefixes="ixsl"
exclude-result-prefixes="this ixsl err xs map"
version="3.0">


<xsl:function name="this:map-deconstruct" as="map(*)*">
<xsl:param name="map" as="map(*)"/>
<xsl:sequence select='
for $key in $map=>map:keys()
return map { $key : $map=>map:get($key) }
'/>
</xsl:function>

<xsl:function name="this:map-entries" as="item()*">
<xsl:param name="map" as="map(*)?"/>
<xsl:sequence select='
if (empty($map)) then ()
else for $key in $map=>map:keys() return $map=>map:get($key)
'/>
</xsl:function>

<xsl:function name="this:map-invert" as="map(*)">
<xsl:param name="map" as="map(*)"/>
<xsl:sequence select='
map:merge(
for $submap in this:map-deconstruct($map) return
for $entry in $submap=>this:map-entries()
return (
map {
(if ($entry instance of xs:anyAtomicType)
then $entry
else string($entry)
):
$submap=>map:keys()
}=>trace("submap")
),
map {"duplicates": "combine"}
)=>trace("merged")
'/>
</xsl:function>

<xsl:template name="test">
<div>
<xsl:variable name="m" as="map(*)">
<xsl:sequence select='map {"a": (1, 2), "b": 2, "c": 1, "d": 3}'/>
</xsl:variable>
<xsl:variable name="x" as="map(*)">
<xsl:sequence select='$m=>this:map-invert()'/>
</xsl:variable>
<xsl:sequence select='
deep-equal(map:keys($x), (1, 2, 3)),
deep-equal($x(1), ("a", "c")),
deep-equal($x(2), ("a", "b")),
deep-equal($x(3), ("d"))
'/>
</div>
</xsl:template>

<xsl:template match="*:button[@id='go']" mode="ixsl:onclick">
<xsl:result-document href="#output" method="ixsl:replace-content">
<xsl:call-template name="test"/>
</xsl:result-document>
</xsl:template>

<xsl:template match="/" name="main">
<xsl:result-document href="#output" method="ixsl:replace-content">
<xsl:call-template name="test"/>
</xsl:result-document>
</xsl:template>

</xsl:stylesheet>
(4-4/4)