Norm Tovey-Walsh or Michael Kay, when trying to fix it, a reduced stylesheet that gives the original error is e.g.
<?xml version="1.0" encoding="UTF-8"?>
<stylesheet exclude-result-prefixes="xs xd dme functx dita mei map array" extension-element-prefixes="ixsl" version="3.0" xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:array="http://www.w3.org/2005/xpath-functions/array" xmlns:dita="http://dita-ot.sourceforge.net" xmlns:dme="http://www.mozarteum.at/ns/dme" xmlns:functx="http://www.functx.com" xmlns:ixsl="http://saxonica.com/ns/interactiveXSLT" xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:mei="http://www.music-encoding.org/ns/mei" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.music-encoding.org/ns/mei">
<xsl:mode on-no-match="shallow-skip"/>
<!--This parameter is a needed for XSpec. Cf. https://github.com/xspec/xspec/wiki/Global-Context-Item-->
<param name="global-context-item" select="."/>
<param name="source" select="'source_A'"/>
<xd:doc>
<xd:desc>
<xd:p>Map staffDef@n of the new scoreDef and @dme.parts.</xd:p>
</xd:desc>
</xd:doc>
<variable as="map(xs:string, item())*" name="map_staves_order">
<for-each select="$global-context-item//choice[@type = 'scoring']/*[@corresp = concat('#', $source)]/scoreDef">
<map>
<for-each select="descendant::staffDef">
<map-entry key="string(@n)" select="@dme.parts"/>
</for-each>
</map>
</for-each>
</variable>
<xd:doc>
<xd:desc>
<xd:p>Get the maximum number of staves.</xd:p>
</xd:desc>
</xd:doc>
<variable as="xs:integer" name="count_staves" select="
max(for $a in map:keys($map_staves_order)
return
if (matches($a, '\d')) then
xs:integer($a)
else
())"/>
<xd:doc>
<xd:desc>
<xd:p>Key: old @n.</xd:p>
<xd:p>Value: new @n</xd:p>
</xd:desc>
</xd:doc>
<variable as="map(xs:string, xs:string)*" name="map_new_old_staves">
<map>
<for-each select="map:keys($map_staves_order)">
<variable name="current_key" select="."/>
<map-entry key="$global-context-item//measure[@n = 1]/staff[@dme.parts = map:get($map_staves_order, $current_key)]/@n/string()" select="."/>
</for-each>
</map>
</variable>
<xsl:template match="/" expand-text="yes">
<debug xmlns="">{serialize($map_new_old_staves, map { 'method' : 'json', 'indent' : true() })}</debug>
</xsl:template>
</stylesheet>
if I add an xsl:message
<?xml version="1.0" encoding="UTF-8"?>
<stylesheet exclude-result-prefixes="xs xd dme functx dita mei map array" extension-element-prefixes="ixsl" version="3.0" xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:array="http://www.w3.org/2005/xpath-functions/array" xmlns:dita="http://dita-ot.sourceforge.net" xmlns:dme="http://www.mozarteum.at/ns/dme" xmlns:functx="http://www.functx.com" xmlns:ixsl="http://saxonica.com/ns/interactiveXSLT" xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:mei="http://www.music-encoding.org/ns/mei" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.music-encoding.org/ns/mei">
<xsl:mode on-no-match="shallow-skip"/>
<!--This parameter is a needed for XSpec. Cf. https://github.com/xspec/xspec/wiki/Global-Context-Item-->
<param name="global-context-item" select="."/>
<param name="source" select="'source_A'"/>
<xd:doc>
<xd:desc>
<xd:p>Map staffDef@n of the new scoreDef and @dme.parts.</xd:p>
</xd:desc>
</xd:doc>
<variable as="map(xs:string, item())*" name="map_staves_order">
<for-each select="$global-context-item//choice[@type = 'scoring']/*[@corresp = concat('#', $source)]/scoreDef">
<map>
<for-each select="descendant::staffDef">
<map-entry key="string(@n)" select="@dme.parts"/>
</for-each>
</map>
</for-each>
</variable>
<xd:doc>
<xd:desc>
<xd:p>Get the maximum number of staves.</xd:p>
</xd:desc>
</xd:doc>
<variable as="xs:integer" name="count_staves" select="
max(for $a in map:keys($map_staves_order)
return
if (matches($a, '\d')) then
xs:integer($a)
else
())"/>
<xd:doc>
<xd:desc>
<xd:p>Key: old @n.</xd:p>
<xd:p>Value: new @n</xd:p>
</xd:desc>
</xd:doc>
<variable as="map(xs:string, xs:string)*" name="map_new_old_staves">
<map>
<for-each select="map:keys($map_staves_order)">
<variable name="current_key" select="."/>
<map-entry key="$global-context-item//measure[@n = 1]/staff[@dme.parts = map:get($map_staves_order, $current_key)]/@n/string()" select="."/>
</for-each>
</map>
</variable>
<xsl:template match="/" expand-text="yes">
<xsl:message>map: {serialize($map_new_old_staves, map { 'method' : 'json', 'indent' : true() })}</xsl:message>
<debug xmlns="">{serialize($map_new_old_staves, map { 'method' : 'json', 'indent' : true() })}</debug>
</xsl:template>
</stylesheet>
I get an error about circularity:
xsl:message evaluation at output-map1.xsl#53 failed: TypeError: Cannot read property 'hashCode' of null
Transformation failure: Error XTDE0640 at output-map1.xsl#53
Circularity in global variable Q{}map_new_old_staves
Error XTDE0640 at output-map1.xsl#53
Circularity in global variable Q{}map_new_old_staves