1

I need to have XSLT call a method on a Java instance that I pass as a parameter. So far I can only get it to work if I create the instance in the XSLT itself. If I attempt to call it on the passed instance it fails with

Exception in thread "main" javax.xml.transform.TransformerConfigurationException: 
Cannot find external method 'Test.get' (must be public).

I can prove the instance is being passed ok by outputting it (it comes out as the toString). Here is my Java:

public class Test {

    public static void main(String[] args) throws Exception {
        Transformer transformer = TransformerFactory.newInstance()
            .newTransformer(
            new StreamSource(Test.class.getResourceAsStream("test.xsl")));
        transformer.setParameter("test1", new Test());
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        transformer.transform(new StreamSource(
            new ByteArrayInputStream(
            "<?xml version=\"1.0\"?><data></data>".getBytes())),
            new StreamResult(outputStream));
        System.out.println(outputStream.toString());
    }

    public String get() {
        return "hello";
    }

    @Override
    public String toString() {
        return "An instance of Test";
    }
}

and here is my xsl:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:test="xalan://Test"
                exclude-result-prefixes="test"
>

    <xsl:param name="test1" />
    <xsl:variable name="test2" select="$test1"/>
    <xsl:variable name="test3" select="test:new()"/>

    <xsl:template match="/">
        <data>
            <!-- proves that the instance is really being passed -->
            <xsl:value-of select="$test1"/>
        </data>
        <data>
            <!-- first two do not work -->
            <!--<xsl:value-of select="test:get($test1)"/>-->
            <!--<xsl:value-of select="test:get($test2)"/>-->
            <!-- this one does work -->
            <xsl:value-of select="test:get($test3)"/>
        </data>
    </xsl:template>
</xsl:stylesheet>

Does anyone know how I can make this work with the passed parameter? Instantiating it in the XSLT is not going to work in my actual use case. Thanks.

4
  • You need to say what XSLT processor you are using. The JAXP API does not define any mechanism for calling from XSLT to Java, and conventions vary between different processors that implement the JAXP API. Commented Feb 17, 2017 at 23:25
  • @Michael Kay I'm using Java 8 and it seems to be picking up Xalan Commented Feb 17, 2017 at 23:27
  • Then sorry, I can't help with Xalan. Commented Feb 18, 2017 at 12:36
  • Possible duplicate of Error when calling java static method from xslt Commented Jan 18, 2018 at 15:40

2 Answers 2

1

In order to get this line working:

<xsl:value-of select="test:get($test1)"/>

The parameter could be passed to a static function:

class Test {

  public static void get(Object context) {
     // here "context" is the instance "test1"
  }
...
Sign up to request clarification or add additional context in comments.

1 Comment

That is the only way I found to call instance methods in Xalan. Strange that it was not upvoted. Although it requires a wrapping to target java method with Object parameter, it works and the wrapping is not a big deal.
0

I also faced same issue. After checking found that we need to use below dependencies

        <dependency>
            <groupId>xalan</groupId>
            <artifactId>serializer</artifactId>
            <version>2.7.2</version>
        </dependency>
        
        
        <dependency>
            <groupId>xalan</groupId>
            <artifactId>xalan</artifactId>
            <version>2.7.2</version>
        </dependency>

After adding these dependencies my code get works.

Comments

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.