XSL does not compile when and only I use xalan:evaluate.

Setting in system properties
sysProps.setProperty("javax.xml.transform.TransformerFactory", "org.apache.xalan.xsltc.trax.SmartTransformerFactoryImpl");
XSLT snippet
<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:xalan="http://xml.apache.org/xalan" exclude-result-prefixes="xalan">

<xsl:template name="my_test_template">
<xsl:param name="my_test_param" />

<xsl:if test="xalan:evaluate($my_test_param)">
some statements
</xsl:if>

<xsl:if test="not(xalan:evaluate($my_test_param))">
some statements
</xsl:if>

</xsl:template>
ERROR LOG
ERROR:  'Cannot find external method 'org.apache.xalan.lib.Extensions.evaluate' (must be public).'
2015-04-14 08:19:52,509 XslTransform ERROR> Error creating 16 template, will skip compile and use interpretive mode instead
javax.xml.transform.TransformerConfigurationException: Could not compile stylesheet
    at org.apache.xalan.xsltc.trax.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:832)
    at org.apache.xalan.xsltc.trax.SmartTransformerFactoryImpl.newTemplates(SmartTransformerFactoryImpl.java:319)

Dani AI

Generated

Short diagnosis for (and to ignore the noise from ): the stylesheet failure when you add a runtime evaluate call is caused by using XSLTC (the compiled/translet path). XSLTC’s compiler does not support the dynamic/evaluate functions (they are part of the dynamic/EXSLT extension and the Xalan interpreter implements them, but XSLTC does not), so compilation fails when the compiler encounters that extension. (xalan.apache.org)

Why it breaks with the SmartTransformerFactory: the “smart” factory will still use XSLTC to produce a Templates object (compiled translet) even if it uses the interpretive engine for one-off Transformer objects. Creating Templates triggers the XSLTC compilation phase, which is where the unsupported extension causes the error. If you precompile or otherwise force XSLTC, the evaluate call will make compilation fail. (xalan.apache.org)

How to fix (practical, testable steps)

  • Use the interpretive Xalan factory instead of XSLTC so the interpreter can handle evaluate:
    System.setProperty("javax.xml.transform.TransformerFactory",
                     "org.apache.xalan.processor.TransformerFactoryImpl");
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer t = tf.newTransformer(new StreamSource(xslFile)); // interpretive
  • Or avoid creating a Templates (don’t precompile). If you must precompile, remove runtime-evaluate usage and refactor so expressions are known at compile time. (xalan.apache.org)

Extra tips

  • xalan:evaluate is provided by Xalan’s Extensions class (and is deprecated in favor of the EXSLT dynamic module); the interpreter provides that implementation. If switching to the interpretive factory doesn’t help, verify the Xalan jars on the classpath include the extensions implementation. For long-term portability, avoid processor-specific xalan: extensions or consider an XSLT processor that supports dynamic evaluation natively (or do the evaluation in Java and pass results into the stylesheet). (xalan.apache.org)
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.