Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Xalan alongside Saxon

I use Xalan in my application, but need to use Saxon with a reference implementation to generate test output to compare with. I want to use them both during unit tests. However, as soon as I add an dependency on Saxon in the project .pom, the application seems to use Saxon for all xslt and XPath operations during tests:

<dependency>
  <groupId>net.sf.saxon</groupId>
  <artifactId>Saxon-HE</artifactId>
  <version>9.4</version>
  <scope>test</scope>
</dependency>

This makes the main application fail when generating output due to a different XPath behaviour. When running the main application outside of test scope it works.

How can I run the main application using Xalan, but the tests using Saxon, during tests?

I have tried setting the following property before running the Xalan and Saxon parts:

System.setProperty("javax.xml.transform.TransformerFactory", "org.apache.xalan.processor.TransformerFactoryImpl ");
System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");

I have also tried to put the Xalan and Saxon parts in different projects, and I have also tried to use them both from a third project, with the same result.

like image 636
Danik Avatar asked Jun 27 '12 11:06

Danik


2 Answers

Avoid relying on the JAXP factory mechanism for selecting your transformation engine. Instead load the engine you want explicitly: it's much more reliable and much faster. For Saxon, replace the call on

TransformerFactory.newInstance()

with

new net.sf.saxon.TransformerFactoryImpl()

and for Xalan use

new org.apache.xalan.processor.TransformerFactoryImpl()
like image 190
Michael Kay Avatar answered Oct 26 '22 16:10

Michael Kay


Here is the solution for completeness:

System.setProperty(XPathFactory.DEFAULT_PROPERTY_NAME + ":"
    + XPathFactory.DEFAULT_OBJECT_MODEL_URI,
    "org.apache.xpath.jaxp.XPathFactoryImpl");
System.setProperty(XPathFactory.DEFAULT_PROPERTY_NAME + ":"
    + NamespaceConstant.OBJECT_MODEL_SAXON,
    "net.sf.saxon.xpath.XPathFactoryImpl");

XPathFactory jaxpFactory =
    XPathFactory.newInstance(XPathFactory.DEFAULT_OBJECT_MODEL_URI);
XPathFactory saxonFactory =
    XPathFactory.newInstance(NamespaceConstant.OBJECT_MODEL_SAXON);
like image 2
Danik Avatar answered Oct 26 '22 16:10

Danik