From an XSLT stylesheet I would like to call a Java (extention) method.
The error message is:
The first argument to the non-static Java function 'doubleIntEcho' is not a valid object reference.
My simplified POC consists of 4 parts:
1. XML: file
<?xml version="1.0"?>
<value>
<amount>1</amount>
<amount>2</amount>
<amount>3</amount>
</value>
- XSLT stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:jcall="java:x.y.z.XsltCallingJavaEchoTwice">
<xsl:output method="xml"/>
<xsl:template match="/value">
<value>
<xsl:apply-templates select="amount"/>
</value>
</xsl:template>
<xsl:template match="amount">
<xsl:copy>
<value>
<xsl:value-of select="text()"/>
</value>
<value-int>
<xsl:value-of select="jcall:doubleIntEcho(number(.))"/>
</value-int>
<value-string>
<xsl:value-of select="jcall:doubleStringEcho(text())"/>
</value-string>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
3. Java class with the extention:
package x.y.z;
public class XsltCallingJavaEchoTwice {
public static String doubleStringEcho( String input) {
return "Source=" input ", echo=" input ", echo2=" input;
}
public static int doubleIntEcho( int input) {
return input input;
}
}
4. The Java environment starting the XSLT transformation process:
public class XsltFilterParentWithAllChildren {
private static final String XML_FILENAME = "files/xslt-call-java-amounts.xml";
private static final String XSLT_FILENAME = "files/xslt-call-java-xsl.xsl";
private static final String XML_OUTPUT_FILENAME = "files/output.xml";
public static void main(String[] args) {
deleteFile( XML_OUTPUT_FILENAME);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try (InputStream is = new FileInputStream(XML_FILENAME)) {
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(is);
try (FileOutputStream output = new FileOutputStream(XML_OUTPUT_FILENAME)) {
transform(doc, output);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void transform(Document doc, OutputStream output) throws TransformerException {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(
new StreamSource(new File(XSLT_FILENAME)));
transformer.transform(new DOMSource(doc), new StreamResult(output));
}
private static void deleteFile( String pathname) {
new File( pathname).delete();
}
}
CodePudding user response:
Looking at https://xalan.apache.org/xalan-j/extensions.html#ext-func-calls I would rather expect e.g. xmlns:java="http://xml.apache.org/xalan/java"
and then e.g. <xsl:value-of select="java:x.y.z.XsltCallingJavaEchoTwice.doubleIntEcho(number(.))"/>
.