[Home] [By Thread] [By Date] [Recent Entries]

Subject: Re: Processor error
From: "rick@xxxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 27 Feb 2026 22:47:43 -0000
Hi Kurt,



Thank you for the detailed explanation. I tried it but get the same error. I
also tried adding the map as a variable of the function, but still get the
error. It works in Oxygen but not in FrameMaker.



    <xsl:function name="cp:find-change-text" as="xs:string">
        <xsl:param name="text"/>
        <xsl:variable name="find-change-map" as="map(xs:string, xs:string)"
            select="map{'&#8212;' : '&lt;emdash/>',
            '&#8211;' : '&lt;endash/>',
            '&#8220;' : '&lt;ldquote/>',
            '&#8221;' : '&lt;rdquote/>',
            '&#8217;' : '&lt;rsquote/>',
            '&#167;'  : '&lt;section/>' }"/>
        <!--<xsl:value-of select="$text"/>-->
        <xsl:sequence select="fold-left(map:keys($find-change-map), $text,
            function($text, $key) { replace($text, $key,
$find-change-map($key)) })"/>
    </xsl:function>


Rick



From: Kurt Cagle kurt.cagle@xxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Sent: Friday, February 27, 2026 5:25 PM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re:  Processor error



Try this:

The error occurs because the inline function inside fold-left closes over the
global variable $find-change-map, and some XSLT 3.0 processors (Saxon in
particular) have trouble with global variable references captured in closures
within named functions. The fix is to pass the map as a parameter to
cp:find-change-text instead of referencing it as a free variable:

<xsl:function name="cp:find-change-text" as="xs:string">
    <xsl:param name="text" as="xs:string"/>
    <xsl:param name="changes" as="map(xs:string, xs:string)"/>
    <xsl:sequence select="fold-left(map:keys($changes), $text,
        function($t, $key) { replace($t, $key, $changes($key)) })"/>
</xsl:function>

Then update the call sites:

<xsl:variable name="text" select="cp:find-change-text(normalize-space(title),
$find-change-map)"/>

The root cause: when an inline function (the lambda passed to fold-left) is
defined inside a named xsl:function, the processor compiles it as an anonymous
function object. If that lambda captures a global variable by reference,
certain processors flag it as an already-bound component during static
analysis b the global binding and the closure binding conflict. Passing the
map explicitly as a parameter keeps everything in the local call stack and
avoids the closure capture entirely.

A secondary issue worth noting: in your templates you have <xsl:text>[ /Title
({$text}) </xsl:text> b those curly braces only trigger AVT expansion inside
attribute values, not inside xsl:text. With expand-text="yes" on the
stylesheet element you'd use {$text} directly in text content, which your
stylesheet does have, but wrapped in xsl:text the expansion still won't fire.
You likely want either bare text content or <xsl:value-of select="$text"/>
there.





Kurt Cagle

Editor in Chief

The Cagle Report

 <mailto:kurt.cagle@xxxxxxxxx> kurt.cagle@xxxxxxxxx

443-837-8725





On Fri, Feb 27, 2026 at 1:28b/PM rick@xxxxxxxxxxxxxx
<mailto:rick@xxxxxxxxxxxxxx>  <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx
<mailto:xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> > wrote:

Hi All,



I am applying a stylesheet via Oxygen using Saxon-EE 9.9.1.7 and it processes
without errors. When I run the same stylesheet in Adobe FrameMaker using
SaxonEE9-8-0-7J, I get this error:



**** Component reference function anon:f_18205168#2 is already bound



When I remove this function, I donbt get the error:



    <xsl:function name="cp:find-change-text" as="xs:string">
        <xsl:param name="text"/>
        <xsl:sequence select="fold-left(map:keys($find-change-map), $text,
            function($text, $key) { replace($text, $key,
$find-change-map($key)) })"/>
    </xsl:function>



Here is a partial input, followed by the stylesheet. I am outputting text.



<?xml version="1.0" standalone="no"?>
<map>
    <chapter name="Chapter1TOC.fm" page="24">
        <title>Chapter 1 Ethics and Professional Conduct</title>
        <practice-notes>
            <bookmark dest="G12.1038988">
                <title>? 1.1 Introduction</title>
                <bookmark dest="G12.1023242">
                    <title>? 1.1:1 The Lawyerbs Creed</title>
                </bookmark>
                <bookmark dest="G12.1023245">
                    <title>? 1.1:2 Notice of Grievance Process</title>
                </bookmark>
            </bookmark>
            <bookmark dest="G12.1023248">
                <title>? 1.2 Sources of Interpretation of Rules</title>
            </bookmark>
        </practice-notes>
        <forms>
            <bookmark name="Form1-1.fm" page="46">
                <title>Form 1-1 Letter Declining Representation</title>
            </bookmark>
            <bookmark name="Form1-2.fm" page="48">
                <title>Form 1-2 Letter Disclosing and Requesting Waiver of
Potential Conflict with Current Client</title>
            </bookmark>
            <bookmark name="Form1-17.fm" page="123">
                <title>Form 1-17 Additional Clauses for Engagement
Letters</title>
                <bookmark dest="G29.1726404">
                    <title>Clause 1-17-1 Corporate Transparency Act</title>
                </bookmark>
                <bookmark dest="G29.1726774">
                    <title>Clause 1-17-2</title>
                </bookmark>
            </bookmark>
        </forms>
    </chapter>
</map>



<?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:cp="http://www.frameexpert.com/functions"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    exclude-result-prefixes="xs cp map"
    version="3.0"
    expand-text="yes">

    <xsl:output method="text" indent="no"/>

    <xsl:variable name="find-change-map" as="map(xs:string, xs:string)"
        select="map{'&#8212;' : '&lt;emdash/>',
                    '&#8211;' : '&lt;endash/>',
                    '&#8220;' : '&lt;ldquote/>',
                    '&#8221;' : '&lt;rdquote/>',
                    '&#8217;' : '&lt;rsquote/>',
                    '&#167;'  : '&lt;section/>' }"/>

    <xsl:template match="/map">
        <xsl:text>[ /PageMode /UseOutlines /DOCVIEW pdfmark&#x0A;</xsl:text>
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="indexes">
        <xsl:variable name="child-count" select="count(index)"/>
        <xsl:text>[ /Title (INDEXES) /Count -</xsl:text>
        <xsl:value-of select="$child-count"/><xsl:text> </xsl:text>
        <!-- Color is black; style is bold. -->
        <xsl:text>/Color [0 0 1] /F 2 /Page 0 /OUT </xsl:text>
        <xsl:text>pdfmark&#x0A;</xsl:text>
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="chapter|index">
        <xsl:variable name="child-count" select="count(bookmark)"/>
        <!-- Call the function to replace special characters with elements.
-->
        <xsl:variable name="text"
select="cp:find-change-text(normalize-space(title))"/>
        <xsl:text>[ /Title ({$text}) </xsl:text>
        <!-- Reserved bookmarks get grey color. -->
        <xsl:if test="matches($text,'reserved$')">
            <xsl:text>/Color [0.5 0.5 0.5] /F 0 </xsl:text>
        </xsl:if>
        <xsl:if test="$child-count > 0">
            <xsl:text>/Count -</xsl:text><xsl:value-of
select="$child-count"/><xsl:text> </xsl:text>
        </xsl:if>
        <xsl:text>/Page </xsl:text><xsl:value-of select="if(@page) then @page
else 0"/><xsl:text> </xsl:text>
        <xsl:text>/View [/XYZ -4 792 null] /OUT </xsl:text>
        <xsl:text>pdfmark&#x0A;</xsl:text>
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="bookmark">
        <xsl:variable name="child-count" select="count(bookmark)"/>
        <!-- Call the function to replace special characters with elements.
-->
        <xsl:variable name="text"
select="cp:find-change-text(normalize-space(title))"/>
        <xsl:text>[ /Title ({$text}) </xsl:text>
        <!-- Reserved bookmarks get grey color. -->
        <xsl:if test="matches($text,'reserved$')">
            <xsl:text>/Color [0.5 0.5 0.5] /F 0 </xsl:text>
        </xsl:if>
        <xsl:if test="$child-count > 0">
            <xsl:text>/Count -</xsl:text><xsl:value-of
select="$child-count"/><xsl:text> </xsl:text>
        </xsl:if>
        <xsl:if test="@page">
            <xsl:text>/Page </xsl:text><xsl:value-of
select="@page"/><xsl:text> </xsl:text>
        </xsl:if>
        <xsl:if test="@dest">
            <xsl:text>/Dest /{@dest} </xsl:text>
        </xsl:if>
        <xsl:text>/OUT pdfmark&#x0A;</xsl:text>
        <xsl:apply-templates/>
    </xsl:template>

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

    <xsl:function name="cp:find-change-text" as="xs:string">
        <xsl:param name="text"/>
        <xsl:sequence select="fold-left(map:keys($find-change-map), $text,
            function($text, $key) { replace($text, $key,
$find-change-map($key)) })"/>
    </xsl:function>

</xsl:stylesheet>

Best regards,

Rick



Rick Quatro

Carmen Publishing Inc.

www.frameexpert.com <http://www.frameexpert.com>

rick@xxxxxxxxxxxxxxx <mailto:rick@xxxxxxxxxxxxxxx>

585-729-6746



XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>

EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/1217935>  (by
email)

XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>

EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/612310>  (by
email <> )

Current Thread
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member