Failed to create XSLT extension in Javascript or Jython using Ant

I am using Ant 1.8 to run some XSLT in documents in a folder. Ant uses Xalan to handle XSLT. The work is done fine, I get a bunch of converted output files corresponding to the input.

The problem is trying to extend XSL using Javascript or Jython to handle some complex strings. Either Javascript or Jython will do, depending on what works first, but at the moment when it is not.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:jython-extension="http://www.jython.org/" xmlns:lxslt="http://xml.apache.org/xslt" xmlns:xalan="http://xml.apache.org/xalan" exclude-result-prefixes="lxslt xalan" xmlns:gotofritz="GotoFritz"> <xalan:component prefix="gotofritz" functions="test"> <xalan:script lang="javascript"> function test(){ return '********* JS WORKS *******'; } </xalan:script> </xalan:component> <lxslt:component prefix="jython-extension" functions="test"> <lxslt:script lang="jpython"> def test(): return "**** JYTHON WORKS ****" </lxslt:script> </lxslt:component> <xsl:template match="/"> <xsl:value-of select="gotofritz:test()"/> <xsl:value-of select="jython-extension:test()"/> </xsl:template> </xsl:stylesheet> 

I downloaded bsf.jar and javascript.har as well as the last xalan jar and moved them to / usr / share / ant / lib - I'm on OS X.

In javscript with the error "Error! Cannot find the GotoFritz class". and "Error! Cannot find external method" GotoFritz.test "(must be public).

Jython Crash with Warning! Unable to resolve function call "http://www.jython.org/:test".

 java.lang.VerifyError: (class: test, method: template$dot$3 signature: (Lcom/sun/org/apache/xalan/internal/xsltc/DOM;Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;I)V) Expecting to find integer on stack at java.lang.Class.getDeclaredConstructors0(Native Method) at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389) at java.lang.Class.getConstructor0(Class.java:2699) at java.lang.Class.newInstance0(Class.java:326) at java.lang.Class.newInstance(Class.java:308) at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getTransletInstance(TemplatesImpl.java:353) at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.newTransformer(TemplatesImpl.java:382) at org.apache.tools.ant.taskdefs.optional.TraXLiaison.createTransformer(TraXLiaison.java:319) at org.apache.tools.ant.taskdefs.optional.TraXLiaison.transform(TraXLiaison.java:177) at org.apache.tools.ant.taskdefs.XSLTProcess.process(XSLTProcess.java:852) at org.apache.tools.ant.taskdefs.XSLTProcess.execute(XSLTProcess.java:388) at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106) at org.apache.tools.ant.Task.perform(Task.java:348) at org.apache.tools.ant.Target.execute(Target.java:390) at org.apache.tools.ant.Target.performTasks(Target.java:411) at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399) at org.apache.tools.ant.Project.executeTarget(Project.java:1368) at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41) at org.apache.tools.ant.Project.executeTargets(Project.java:1251) at org.apache.tools.ant.Main.runBuild(Main.java:809) at org.apache.tools.ant.Main.startAnt(Main.java:217) at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280) at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109) 

It seems to me that Xalan treats both extensions as Java instead of using BSF. Any ideas? thanks in advance.

+4
source share
1 answer

It works for me using this stylesheet (xalanext.xsl):

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xalan" xmlns:js-extension="http://example.com" xmlns:jython-extension="http://www.jython.org/" exclude-result-prefixes="xalan js-extension jython-extension"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xalan:component prefix="js-extension" functions="test"> <xalan:script lang="javascript"> function test(){ return '********* JS WORKS *******'; } </xalan:script> </xalan:component> <xalan:component prefix="jython-extension" functions="test"> <xalan:script lang="jython"> def test(): return "**** JYTHON WORKS ****" </xalan:script> </xalan:component> <xsl:template match="/"> <result> <javascript><xsl:value-of select="js-extension:test()"/></javascript> <jython><xsl:value-of select="jython-extension:test()"/></jython> </result> </xsl:template> </xsl:stylesheet> 

Here is my Ant build file:

 <project name="xalanext" default="runxslt"> <path id="xslt.processor.classpath"> <pathelement path="xalan.jar"/> <pathelement path="bsf.jar"/> <pathelement path="js.jar"/> <pathelement path="jython.jar"/> <pathelement path="commons-logging-1.0.4.jar"/> </path> <target name="runxslt"> <xslt classpathref="xslt.processor.classpath" in="test.xml" out="out.xml" basedir="." destdir="." extension=".xml" style="xalanext.xsl"> </xslt> </target> </project> 

test.xml is a small dummy document containing only <root/> .

Result in out.xml:

 <result> <javascript>********* JS WORKS *******</javascript> <jython>**** JYTHON WORKS ****</jython> </result> 

Comments:

  • bsf.jar from BSF 2.4.0. Using bsf-all-3.1.jar from BSF 3.1 gives me org.apache.xalan.extensions.ObjectFactory$ConfigurationError: Provider org.apache.bsf.BSFManager not found .
  • The Jython script language is set as jython (not jpython ) in the stylesheet.
  • The definition of the test() function of Jython starts in the leftmost column (Jython is picky about the space).
  • A JavaScript implementation is needed (the question mentions something called "javascript.har", but I don't know what it is). js.jar contains an Rhino engine. Rhino ships in Oracle Java 1.6 and later, but I was unable to get it to work if js.jar was not in the classpath.
  • I needed to add a jar of error messages to the classpath to avoid java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory .
  • Xalan serializer.jar should be in the same directory as xalan.jar to avoid XSLT Error (java.lang.NoClassDefFoundError): org/apache/xml/serializer/ExtendedContentHandler .
+3
source

Source: https://habr.com/ru/post/1403239/


All Articles