2

I am trying to call JavaScript inside XSLT but it keeps on failing. I am using the Xalan namespace. I'm calling Java as well and that works no problem, but for some reason the JavaScript doesn't.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:java="http://xml.apache.org/xalan/java" xmlns:xalan="http://xml.apache.org/xalan" xmlns:counter="MyCounter" extension-element-prefixes="counter">
<xsl:template match="/">
    <xalan:component prefix="counter" functions="response">
        <xalan:script lang="javascript">

          function response(name) {
            // Return a string.
            return "" + (name);
          }

        </xalan:script>
     </xalan:component>

    <xsl:value-of select="counter:response('hello')"/> 
    <xsl:variable name="rightNow" select="java:java.util.Date.new()"/><!-- Get date object -->
    <xsl:variable name="formatter" select="java:java.text.SimpleDateFormat.new('MM')"/> <!-- double digit format: append 0 to less than ten -->  
    <xsl:variable name="formattedMonth" select="java:format($formatter, $rightNow)"/> <!-- format it -->
    <p><xsl:value-of select="$formattedMonth"/></p> 
</xsl:template> 
</xsl:stylesheet> 

I get this error in the XML transformer:

<Location of error unknown>java.lang.NoSuchMethodException: For extension function, could not find method java.lang.String.response<ExpressionContext, ]>.
2
  • I think script tag is enough, it probably doesn't require xalan prefix <script type="text/javascript"> Commented Sep 18, 2013 at 11:18
  • Shouldn't you have functions="response" in the xalan:component element? Commented Sep 18, 2013 at 14:37

1 Answer 1

6
  1. Follow Apache's Xalan-Java JavaScript extension instructions, especially being careful to include js.jar and bsf.jar on your classpath. (Important, but probably not your problem or you would have seen helpful stacktraces.)
  2. See also this related SO question. (Useful, but you've probably already seen.)
  3. As @JLRishe mentioned, add functions="response" to xalan:component. (Proper, but seems not to be strictly necessary, at least in this case.)
  4. Move xalan:component out of xsl:template. (Critical. This is likely the problem here.)

So, running your code thus modified:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:java="http://xml.apache.org/xalan/java"
                xmlns:xalan="http://xml.apache.org/xalan"
                xmlns:counter="MyCounter"
                extension-element-prefixes="counter">

  <xalan:component prefix="counter" functions="response">
    <xalan:script lang="javascript">

      function response(name) {
        // Return a string.
        return "" + (name);
      }

    </xalan:script>
  </xalan:component>

  <xsl:template match="/">
    <xsl:value-of select="counter:response('hello')"/> 
    <xsl:variable name="rightNow" select="java:java.util.Date.new()"/><!-- Get date object -->
    <xsl:variable name="formatter" select="java:java.text.SimpleDateFormat.new('MM')"/> <!-- double digit format: append 0 to less than ten -->  
    <xsl:variable name="formattedMonth" select="java:format($formatter, $rightNow)"/> <!-- format it -->
    <p><xsl:value-of select="$formattedMonth"/></p> 
  </xsl:template> 
</xsl:stylesheet>

Yields the following output as expected:

<?xml version="1.0" encoding="UTF-8"?>hello<p xmlns:xalan="http://xml.apache.org/xalan" xmlns:java="http://xml.apache.org/xalan/java">09</p>
Sign up to request clarification or add additional context in comments.

2 Comments

Hi, thanks for answering. A none related question, what is MyCounter and why is it declared in the namespace? This is from the xalan examples
The XSLT extension mechanism is leveraging the XML namespace mechanism. 'MyCounter' probably is vestigial from the JavaScript extension example given here: xml.apache.org/xalan-j/extensions.html You will want to rename it and the 'counter' prefix to something more appropriate for your application, but at least you have working code with which to start.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.