I don't have any direct experience with calling java from Saxon, but the
error:

>  Cannot load Java class java:runDaffodil.

implies to me that Saxon is unable to find the .class file. Did you add
that file to the classpath? You'll also need to add all the Daffodil
jars to the classpath as well.


Do you get the same error if you have much simpler function? E.g.

  public static int two() {
    return 2;
  }

and

  <xsl:value-of select="dfdl:two()" xmlns:dfdl="java:runDaffodil" />

If that also fails, that would rule out any Daffodil specific issues,
and the issue is likely the classpath or something else.

On 5/28/20 7:59 AM, Roger L Costello wrote:
> Hi Folks, 
> 
> I saw the "hello world" file on github:
> https://github.com/OpenDFDL/examples/blob/master/helloWorld/src/main/java/HelloWorld.java
> 
> I got it working. However, for me, it has two disadvantages:
> 
> 1. It only works with XSLT 1.0
> 2. The Java code calls the XSLT code. I want it the other way around: I want 
> the XSLT code to call the Java code.
> 
> I want to have a Java program that can be called from XSLT. The XSLT will 
> pass to the Java program the name of the DFDL schema file and the name of the 
> input file. I want the Java program to call Daffodil, requesting that it 
> parse the input file using the schema file. I want the Java program to return 
> XML. 
> 
> I am using Saxon as my XSLT processor. The Saxon web site 
> (https://www.saxonica.com/html/documentation/extensibility/functions/staticmethods.html)
>  says that, using Saxon, an XSLT program can call static Java methods. 
> 
> Below is the Java program (runDaffodil.java) that I created (it is a slight 
> modification of the hello world program). I created a static method named 
> doTransform. It takes two arguments: the name of a DFDL schema and the name 
> of the input file. Does it appear to be correct? It seems to compile okay, 
> producing runDaffodil.class.
> 
> When I run this XSLT:
> -------------------------------------------------------------------------
> <xsl:variable name="dfdl" select="doc('csv.dfdl.xsd')"/>
> <xsl:variable name="input" select="doc('csv.txt')"/>
> 
> <xsl:template match="/">
>     <xsl:value-of select="dfdl:doTransform($dfdl, $input)" 
>         xmlns:dfdl="java:runDaffodil"/>
> </xsl:template>
> -------------------------------------------------------------------------
> Saxon generates this error:
> 
> Static error in {dfdl:doTransform($dfdl, $input...} in expression in 
> xsl:value-of/@select on line 10 column 44 of processCSV.xsl: XPST0017: Cannot 
> find a 2-argument function named Q{java:runDaffodil}doTransform(). Cannot 
> load Java class java:runDaffodil.
> 
> I included runDaffodil.class in my classpath.
> 
> Any suggestions on how to fix this?  /Roger
> ----------------------------------------------------
> import java.io.File;
> import java.io.IOException;
> import java.net.URISyntaxException;
> import java.net.URL;
> import java.util.Collections;
> import java.util.List;
> import java.util.Map;
> 
> import org.jdom2.Content;
> import org.jdom2.Document;
> import org.jdom2.Namespace;
> import org.jdom2.filter.ContentFilter;
> import org.jdom2.output.XMLOutputter;
> import org.jdom2.transform.XSLTransformException;
> import org.jdom2.transform.XSLTransformer;
> import org.jdom2.xpath.XPathExpression;
> import org.jdom2.xpath.XPathFactory;
> 
> import org.apache.daffodil.japi.Compiler;
> import org.apache.daffodil.japi.Daffodil;
> import org.apache.daffodil.japi.DataProcessor;
> import org.apache.daffodil.japi.Diagnostic;
> import org.apache.daffodil.japi.ParseResult;
> import org.apache.daffodil.japi.ProcessorFactory;
> import org.apache.daffodil.japi.UnparseResult;
> import org.apache.daffodil.japi.infoset.JDOMInfosetInputter;
> import org.apache.daffodil.japi.infoset.JDOMInfosetOutputter;
> import org.apache.daffodil.japi.infoset.JsonInfosetOutputter;
> import org.apache.daffodil.japi.io.InputSourceDataInputStream;
> 
> public class runDaffodil {
> 
>     public static XMLOutputter doTransform(String dfdl, String input) throws 
> IOException, XSLTransformException, URISyntaxException {
> 
>         URL dfdlURL = runDaffodil.class.getResource(dfdl);
>         URL inputURL = runDaffodil.class.getResource(input);
> 
>         //
>         // First, compile the DFDL Schema
>         //
>         Compiler c = Daffodil.compiler();
>         ProcessorFactory pf = c.compileSource(dfdlURL.toURI());
>         if (pf.isError()) {
>             // didn't compile schema. Must be diagnostic of some sort. 
>             List<Diagnostic> diags = pf.getDiagnostics();
>             for (Diagnostic d : diags) {
>                 System.err.println(d.getSomeMessage());
>             }
>             System.exit(1);
>         }
>         DataProcessor dp = pf.onPath("/");
>         if (dp.isError()) {
>             // didn't compile schema. Must be diagnostic of some sort.
>             List<Diagnostic> diags = dp.getDiagnostics();
>             for (Diagnostic d : diags) {
>                 System.err.println(d.getSomeMessage());
>             }
>             System.exit(1);
>         }
>         //
>         // Parse - parse data to XML
>         //
>         java.io.InputStream is = inputURL.openStream();
>         InputSourceDataInputStream dis = new InputSourceDataInputStream(is);
>         //
>         // Setup JDOM outputter
>         // 
>         JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
> 
>         // Do the parse
>         //
>         ParseResult res = dp.parse(dis, outputter);
> 
>         // Check for errors
>         //
>         boolean err = res.isError();
>         if (err) {
>             // didn't parse the data. Must be diagnostic of some sort.
>             List<Diagnostic> diags = res.getDiagnostics();
>             for (Diagnostic d : diags) {
>                 System.err.println(d.getSomeMessage());
>             }
>             System.exit(2); 
>         }
>         
>         Document doc = outputter.getResult();
>         //
>         // if we get here, we have a parsed infoset result!
>         // Note that if we had only wanted this text, we could have used
>         // a different outputter to create XML text directly,
>         // but below we're going to transform this JDOM tree.
>         //
>         XMLOutputter xo = new 
> XMLOutputter(org.jdom2.output.Format.getPrettyFormat());
>         return xo;
>     }
> }
> 

Reply via email to