In the script used to compile the stylesheet and then run the compiled version, your extension element factory isn't on the classpath during the compile phase. This means that the expression element-available('abc:xyz') compiles to "false", and at run-time the code simply takes the "false" path. In fact, no attempt will be made to compile the code corresponding to your extension element. This isn't just an accident of the fact that element-available('abc:xyz') is precomputed; the factory code is actually needed at compile time.
 
Let me try and answer some of your supplementary questions below:


From: Chris von See [mailto:chris@techadapt.com]
Sent: 25 March 2008 17:21
To: Michael Kay
Cc: Mailing list for the SAXON XSLT and XQuery processor
Subject: Re: Saxon extension elements not executed with precompiled stylesheet?


On Mar 25, 2008, at 7:24 AM, Michael Kay wrote:

The answer is that in general it's possible, but it's the responsibility of the implementor of the extension element to make sure that all the objects used in the compiled representation are Serializable.
If it fails, then I would normally expect it to fail when compiling, not when running.

I'm not sure I understand your comment. The stylesheet runs with no problem when it is not compiled using net.sf.saxon.Compile, but fails when it is compiled. The two runs were conducted using the same classpath, same stylesheet source, same source document and same parameters - the only difference is the compilation of the stylesheet. Can you help me understand where serialization comes into the picture? 
 
As explained above, the extension element factory (and the classes it instantiates) need to be available at compile time, not just at runtime.
 
The reference here to "serialization" is Java serialization (not XML serialization). The .sxx file generated by Compile is really just a Java serialization of the expression tree produced by the Saxon compiler. For it to work, every object referenced from the expression tree needs to implement the Java pseudo-interface Serializable, and this includes objects used in the compiled code of user-defined extension elements. If there are non-serializable objects on the tree, the failures can be obscure to diagnose.
 
Michael Kay
http://www.saxonica.com/
 
 

Normally element-available() takes a string literal as its argument, and in that case it's evaluated at compile time. I'm therefore surprised that it should cause a run-time failure.
I think you'll need to send me some code that I can look at more carefully.

Here's the stylesheet itself:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:dtbook="http://www.daisy.org/z3986/2005/dtbook/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="2.0"
exclude-result-prefixes="#all"
xmlns:java="http://saxon.sf.net/java-type"
xmlns:tamc="java:/techadapt.accessiblemediacenter.converter.saxon.TAMCElementFactory"
extension-element-prefixes="tamc" >
<!-- -->
<xsl:param name="maxImageWidth" >600</xsl:param>
<xsl:param name="maxImageHeight" >600</xsl:param>
<xsl:param name="contentPath" />
<!-- -->
<xsl:output name="content-format" method="xhtml" indent="no" encoding="UTF-8"
omit-xml-declaration="yes"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
/>
<!-- -->
<xsl:strip-space elements="dtbook:* *"/>
<!-- -->
<xsl:template match="/">
<!-- Make sure our extension elements are available -->
<xsl:if test="element-available('tamc:constructImageElementWithValidation')">
<xsl:message terminate="no">constructImageElementWithValidation extension element ***IS*** available</xsl:message>
</xsl:if>
<xsl:if test="not(element-available('tamc:constructImageElementWithValidation'))">
<xsl:message terminate="yes">constructImageElementWithValidation extension element ***IS NOT*** available</xsl:message>
</xsl:if>
<xsl:apply-templates />
</xsl:template>
<!-- -->
<xsl:template match="dtbook:img">
<xsl:message terminate="no">Calling constructImageElementWithValidation on image <xsl:value-of select="@src" />, width <xsl:value-of select="@width" /> x height <xsl:value-of select="@height" /></xsl:message>
<tamc:constructImageElementWithValidation src="{@src}" alt="{@alt}" width="{@width}" height="{@height}" class="{@class}" id="{@id}"
maxImageWidth="{$maxImageWidth}" maxImageHeight="{$maxImageHeight}" contentPath="{$contentPath}" />
</xsl:template>
<!-- -->
</xsl:stylesheet>


Here's the script I used to invoke the non-compiled version:

java -cp /Users/cvonsee/devtools/saxonb9-0-0-2j/saxon9.jar:/Users/cvonsee/myworkspace/AccessibleMediaCenter/webapps/accessiblemediacenter/WEB-INF/classes net.sf.saxon.Transform -o:"/Users/cvonsee/temp/saxon test/outputStandalone.xml" -xsl:"/Users/cvonsee/temp/saxon test/ss.xsl" "/Network/Servers/salmon/data3/CAST NIMAS Exemplars/Exemplar 6/NIMAS Exemplar6 - Science - Baseline 1.1 Folder/NIMASExemplar6Science.xml" contentPath="/Network/Servers/salmon/data3/CAST NIMAS Exemplars/Exemplar 6/NIMAS Exemplar6 - Science - Baseline 1.1 Folder"

Here's output from the non-compiled version:

constructImageElementWithValidation extension element ***IS*** available
Calling constructImageElementWithValidation on image ./images/U01C02/p011-001.jpg, width x height
Calling constructImageElementWithValidation on image ./images/U01C02/p012-001.jpg, width x height
<snip more messages from template>


Here's the script I used to invoke the compiled version:

java -cp /Users/cvonsee/devtools/saxonb9-0-0-2j/saxon9.jar net.sf.saxon.Compile ss.xsl ss.sxx
java -cp /Users/cvonsee/devtools/saxonb9-0-0-2j/saxon9.jar:/Users/cvonsee/myworkspace/AccessibleMediaCenter/webapps/accessiblemediacenter/WEB-INF/classes net.sf.saxon.Transform -o:"/Users/cvonsee/temp/saxon test/outputStandalone.xml" -c:"/Users/cvonsee/temp/saxon test/ss.sxx" "/Network/Servers/salmon/data3/CAST NIMAS Exemplars/Exemplar 6/NIMAS Exemplar6 - Science - Baseline 1.1 Folder/NIMASExemplar6Science.xml" contentPath="/Network/Servers/salmon/data3/CAST NIMAS Exemplars/Exemplar 6/NIMAS Exemplar6 - Science - Baseline 1.1 Folder"

Here's the output from the script used to invoke the compiled version:

Serializing compiled stylesheet
Finished serializing stylesheet
constructImageElementWithValidation extension element ***IS NOT*** available
Processing terminated by xsl:message at line 29 in ss.xsl


Let me know if you need more info.


Cheers
Chris

Begin forwarded message:

From: Chris von See <chris@techadapt.com>
Date: March 21, 2008 8:53:24 AM PDT
To: Chris von See <chris@techadapt.com>
Subject: Saxon extension elements not executed with precompiled stylesheet?

Hi -

Using Saxon-B 9.0.0.2 for Java and JDK 1.5.04, I wrote a Saxon extension element which is called correctly when the stylesheet is invoked using the -xsl: option on the command line. However, when I compile that same stylesheet and run it from the command line using the -c option I get an error (generated by evaluating element-available() in the stylesheet) indicating that the extension element is not available. In both cases the classpath is the same, and the only change is the use of the compiled stylesheet and the -c vs -xsl option. Can Saxon call extension elements from precompiled stylesheets?

Thanks
Chris von See
TechAdapt, Inc.