2012-06-27 11 views
6

Uso Xalan nella mia applicazione, ma è necessario utilizzare Saxon con un'implementazione di riferimento per generare un output di test da confrontare. Voglio usarli entrambi durante i test unitari. Tuttavia, non appena aggiungo una dipendenza Saxon nel .pom progetto, l'applicazione sembra utilizzare Saxon per tutte le operazioni XSLT e XPath durante le prove:Utilizzo di Xalan con Saxon

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

Questo rende l'applicazione principale sicuro quando si genera l'uscita dovuta a un diverso comportamento XPath. Funziona quando si esegue l'applicazione principale al di fuori dell'ambito di test.

Come è possibile eseguire l'applicazione principale utilizzando Xalan, ma i test utilizzando Saxon, durante i test?

Ho provato impostando la seguente proprietà prima di eseguire le Xalan e sassoni parti:

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

Ho anche provato a mettere le parti Xalan e sassoni in diversi progetti, e ho anche cercato di usarli entrambi da un terzo progetto, con lo stesso risultato.

risposta

10

Evitare di fare affidamento sul meccanismo di fabbrica JAXP per la selezione del motore di trasformazione. Invece, carica il motore che vuoi esplicitamente: è molto più affidabile e molto più veloce. Per Sassone, sostituire la chiamata in

TransformerFactory.newInstance() 

con

new net.sf.saxon.TransformerFactoryImpl() 

e per Xalan utilizzare

new org.apache.xalan.processor.TransformerFactoryImpl() 
+0

ne fanno il XPath parte che sta fallendo però. C'è un modo per dire a XPathFactory di usare l'implementazione di default? Questa risposta dice come fare il contrario, usa l'implementazione Saxon http://stackoverflow.com/questions/926222/using-saxon-xpath-engine-in-java. – Danik

+1

Questo sarebbe org.apache.xpath.jaxp.XPathFactoryImpl come da http://www.jarvana.com/jarvana/view/xalan/xalan/2.7.0/xalan-2.7.0.jar!/org/apache/ XPath/JAXP/XPathFactoryImpl.class? classDetails = ok. In ogni caso, suggerirei di utilizzare il meccanismo JAXP per l'applicazione anziché renderlo dipendente dall'implementazione, a meno che non ci siano casi estremi di utilizzo nell'applicazione. Utilizzare solo il codice impl-dependent nei test. –

+2

Non sono d'accordo. Un sacco di persone si scontrano perché usano il meccanismo JAXP e acquisiscono un processore XPath 2.0 quando la loro applicazione richiede un processore XPath 1.0. Non è possibile chiedere esplicitamente un processore XPath 1.0; se non dici quello che vuoi, non sai cosa otterrai e potrebbe non funzionare. –

2

Ecco la soluzione per completezza:

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);