Project

Profile

Help

RE: ClassCastException: net.sf.saxon.expr.instruct.CopyOf... » position-accumulator.xsl

Martin Honnen, 2020-09-10 13:13

 
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="3.0">
<xsl:function name="mf:path" as="xs:string" streamability="inspection" visibility="public">
<xsl:param name="node" as="node()"/>
<xsl:sequence
select="$node/ancestor-or-self::*
!(
'Q{' || namespace-uri-from-QName(node-name()) || '}' || local-name() ||
'[' ||
accumulator-before('position')[last() - 1](node-name())
|| ']'
) => string-join('/')"/>
</xsl:function>
<xsl:function name="mf:position" as="xs:integer" streamability="inspection" visibility="public">
<xsl:param name="node" as="node()"/>
<xsl:sequence select="$node!accumulator-before('position')[last() - 1](node-name())"/>
</xsl:function>
<xsl:accumulator name="position" as="map(xs:QName, xs:integer)*" initial-value="map{}" streamable="yes">
<xsl:accumulator-rule match="*"
select="let $cm := $value[last()],
$node-name := node-name()
return
if (map:contains($cm, $node-name))
then ($value[position() lt last()], map:put($cm, $node-name, $cm($node-name) + 1), map{})
else ($value[position() lt last()], map:put($cm, $node-name, 1), map {})"/>
<xsl:accumulator-rule match="*" phase="end"
select="$value[position() lt last()]"/>
</xsl:accumulator>
</xsl:stylesheet>
(2-2/3)