0

I'm writing a Java application, where the goal is to do XML transformation to generate a PDF document. I'm using an XML file as input, which is first parsed to a java object. After parsing I want to use that object in the XML transformation, so I set it as a parameter for the transformer:

TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(new StreamSource(stylesheet));
transformer.setParameter("foo", javaObject);

An instance method of that object is called in the xsl stylesheet like this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
                xmlns:fo="http://www.w3.org/1999/XSL/Format"
                xmlns:pdf="http://xmlgraphics.apache.org/fop/extensions/pdf"
                xmlns:MyClass="foo.bar.MyClass"
>
...
<xsl:param name="foo"/>
<xsl:param name="seller" select="MyClass:myMethod($foo)"/>

My question is: is this a proper way to do this? Which XSLT processor is suitable for using parameters this way? Is there another way to do it?

I tried out Xalan (org.apache.xalan.xsltc.trax.TransformerFactoryImpl) but I get an Exception that the method cannot be found:

ERROR:  'Cannot find external method 'foo.bar.MyClass.myMethod' (must be public).'
FATAL ERROR:  'Could not compile stylesheet'

The method is public and has no arguments.

greggor
  • 33
  • 4

1 Answers1

0

For Saxon: Information on "reflexive" calls to external Java objects can be found at http://www.saxonica.com/documentation/index.html#!extensibility/functions

The first thing to note is that it requires Saxon-PE or -EE.

If it's an instance-level (non-static) method with no parameters, then the simplest approach is:

(a) declare a namespace corresponding to the class name, for example

xmlns:date="java:java.util.Date"

(b) call the method with the external object as the first argument:

date:getTime($date)

The Saxon and Xalan mechanisms are not identical, though there are many similarities.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
  • Thank you for the answer. In addition, I also need to set the secure processing feature (FEATURE_SECURE_PROCESSING) which, as I assume, disallows calling instance methods in the stylesheet. I already made it work with Saxon-EE (I had to set another feature "ALLOW_EXTERNAL_FUNCTIONS"), but still want to know if it's possible with Xalan too. Could you please tell me if I can use that mechanism with the secure feature in Xalan? – greggor Dec 18 '19 at 16:05
  • I can't help you with Xalan, sorry. – Michael Kay Dec 19 '19 at 00:15
  • Thank you anyway. I have another question: Which license should be bought for a commercial product where Saxon-EE or PE is integrated as an external dependency? The product is a SOAP web service which produces pdf files for every request. Is more than one license needed if there are more stages like: "development", "test", "production" etc.? What, if the company needs to upload the library to the nexus? Could you please give me some information? I already tried to read the license terms but don't understand a word. – greggor Jan 09 '20 at 15:57
  • Happy to discuss this with you, but it's not an appropriate subject for StackOverflow. Please contact us via the contact information on www.saxonica.com. – Michael Kay Jan 09 '20 at 17:54