Saxon transformation via Ant: how to pass sourceParserClass

Having trouble installing Oxygen? Got a bug to report? Post it all here.
Ron Van den Branden
Posts: 65
Joined: Fri Jan 18, 2008 5:54 pm

Saxon transformation via Ant: how to pass sourceParserClass

Post by Ron Van den Branden »

Hi,

I'm trying to set up an Ant transformation scenario in Oxygen 15.0, invoking Saxon via the XSLT Ant task. I've succesfully figured out how to pass on XML catalog files so Saxon can locate the DTD and entity files independent of the exact location of the XML source files that are being transformed. Yet, when the XSLT stylesheet loads documents via the collection() function, the process exits with errors because DTD and entity files that are referenced in the XML files which are loaded via the collection() function are not found.

From the Saxon documentation at <http://www.saxonica.com/documentation/s ... alogs.html> I've understood that specific options should be passed to Saxon in order to make doc() and collection() honour catalog files. Indeed, following direct command line call to Saxon works:

Code: Select all


  java  -cp %SAXON_HOME%/saxon9.jar;resolver-1.2.jar \
-Dxml.catalog.files=catalog.xml net.sf.saxon.Transform \
-r org.apache.xml.resolver.tools.CatalogResolver \
-x org.apache.xml.resolver.tools.ResolvingXMLReader
-it main stylesheet.xsl
Yet, I'm struggling to pass these parameters to my Ant build file. I've looked up the corresponding Saxon configuration field names (<http://saxonica.com/documentation/confi ... tures.html>) to be passed on as <attribute> arguments in the XSLT Ant task, but it doesn't seem to work. This is how far I got:

Code: Select all


  <target name="convert-folder">
<xslt force="yes" style="${pd}/stylesheet.xsl" in="${pd}/input.xml" out="${outputFile}">
<xmlcatalog>
<catalogpath>
<pathelement location="${pd}/catalog.xml"/>
</catalogpath>
</xmlcatalog>
<factory name="net.sf.saxon.TransformerFactoryImpl">
<attribute name="http://saxon.sf.net/feature/initialTemplate" value="main"/>
<!-- see http://saxonica.com/documentation/configuration/config-features.html -->
<attribute name="http://saxon.sf.net/feature/uriResolverClass" value="org.apache.xml.resolver.tools.CatalogResolver"/>
<attribute name="http://saxon.sf.net/feature/sourceParserClass" value="org.apache.xml.resolver.tools.ResolvingXMLReader"/>
</factory>
<classpath location="${oxygenlib}/saxon9ee.jar"/>
</xslt>
</target>
Yet, the process exits with a notification:

Code: Select all


    [xslt] Cannot find CatalogManager.properties
...and errors about unfound entity files (note: not about the DTD files), for which Saxon clearly uses the paths inside the source documents, rather than those in the catalog.xml file. I don't know if the CatalogManager.properties error points to a classpath issue, but the required resolver.jar file is included in the list of libraries passed within Oxygen to the Ant call:

Code: Select all


  <field name="extensionURLs">
<String-array>
<String>${oxygenHome}/classes/</String>
<String>${oxygenHome}/lib/oxygen.jar</String>
<String>${oxygenHome}/lib/oxygenAuthor.jar</String>
<String>${oxygenHome}/lib/oxygenDeveloper.jar</String>
<String>${oxygenHome}/lib/oxygenEclipse.jar</String>
<String>${oxygenHome}/lib/oxygenAuthorEclipse.jar</String>
<String>${oxygenHome}/lib/oxygenDeveloperEclipse.jar</String>
<String>${oxygenHome}/lib/resolver.jar</String>
<String>${oxygenHome}/lib/xercesImpl.jar</String>
<String>${oxygenHome}/lib/saxon9ee.jar</String>
<String>${oxygenHome}/lib/saxon.jar</String>
<String>${oxygenHome}/lib/xml-apis-ext.jar</String>
<String>${oxygenHome}/lib/log4j.jar</String>
</String-array>
</field>
Could anyone point me in the good direction to make Saxon honour the catalog information for collection() function calls?

Any help much appreciated!

Ron
adrian
Posts: 2855
Joined: Tue May 17, 2005 4:01 pm

Re: Saxon transformation via Ant: how to pass sourceParserCl

Post by adrian »

Hi,

If it works with the command line Saxon, try something closer to that in ANT:

Code: Select all

<java classname="net.sf.saxon.Transform">
<classpath>
<pathelement path="saxon9.jar"/>
</classpath>
<arg value="-Dxml.catalog.files=catalog.xml"/>
...
Note that the Saxon-EE distribution from Oxygen is only licensed to be used from the Oxygen GUI. If you use in ANT the saxon9ee.jar from the Oxygen lib folder, it will run in fallback mode as Saxon-HE (with a reduced feature set).

Regards,
Adrian
Adrian Buza
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com
Ron Van den Branden
Posts: 65
Joined: Fri Jan 18, 2008 5:54 pm

Re: Saxon transformation via Ant: how to pass sourceParserCl

Post by Ron Van den Branden »

Many thanks, Adrian!

Recasting the <xslt> task to a <java> task works. Fortunately I don't use extension functions in my stylesheets, so I can do with Saxon-he.

In case it might helps others, I'll include the <java> equivalent of my original command line example below:

Code: Select all


  <target name="convert-folder">
<java classname="net.sf.saxon.Transform">
<classpath>
<pathelement path="${classpath}"/>
<pathelement path="${oxygenlib}/saxon9ee.jar"/>
<pathelement path="${oxygenlib}/resolver.jar"/>
<pathelement path="${pd}/catalogFolder"/>
</classpath>
<arg value="-s:${pd}/input.xml"/>
<arg value="-xsl:${pd}/stylesheet.xsl"/>
<arg value="-o:${outputFile}"/>
<arg value="-it:main"/>
<arg value="-r:org.apache.xml.resolver.tools.CatalogResolver"/>
<arg value="-x:org.apache.xml.resolver.tools.ResolvingXMLReader"/>
</java>
</target>
Note how the catalog file location can't just be passed with

Code: Select all

<arg value="-Dxml.catalog.files=catalog.xml"/>
because Saxon will interpret it as an invalid Saxon option. Recasting it as

Code: Select all

<jvmarg value="-Dxml.catalog.files=catalog.xml"/>

didn't work either, but throws a warning:

Code: Select all


     [java] JVM args ignored when same JVM is used.
Instead, the location of the catalog file should be declared in a dedicated CatalogManager.properties file, whose folder should be on the classpath. Hence, my updated code example above includes a folder ${pd}/catalogFolder in the classpath, where this file lives. I have found these valuable bits of information in http://www.sagehill.net/docbookxsl/UseCatalog.html; more details can be found there.

Concerning my original question: I think I have found evidence that the core of the problem lies in passing the classpath/certain configuration options via the <xslt> Ant task (see http://markmail.org/message/r6awkb5atliwp7ht and http://markmail.org/message/qsk7cvb3pt7j5337). I have tried to modify my original <xslt> task, but didn't manage to get Saxon pick up the CatalogManager.properties file via the classpath. So, the <java> task seems the safest option, indeed.

Best,

Ron
adrian
Posts: 2855
Joined: Tue May 17, 2005 4:01 pm

Re: Saxon transformation via Ant: how to pass sourceParserCl

Post by adrian »

Ron Van den Branden wrote:Note how the catalog file location can't just be passed with

Code: Select all

<arg value="-Dxml.catalog.files=catalog.xml"/>
because Saxon will interpret it as an invalid Saxon option. Recasting it as

Code: Select all

<jvmarg value="-Dxml.catalog.files=catalog.xml"/>

didn't work either, but throws a warning:

Code: Select all


     [java] JVM args ignored when same JVM is used.
Sorry about the confusion. You are right, -D args should be passed to the JVM with jvmarg.
Note that you can use jvmarg if you fork the java process:

Code: Select all

<java classname="net.sf.saxon.Transform" fork="yes">
Regards,
Adrian
Adrian Buza
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com
Ron Van den Branden
Posts: 65
Joined: Fri Jan 18, 2008 5:54 pm

Re: Saxon transformation via Ant: how to pass sourceParserCl

Post by Ron Van den Branden »

Ah, indeed, that works too!

Many thanks again for your kind help with my (lack of) basic Ant skills.

Best,

Ron
Post Reply