2009-07-07 9 views
7

Devo elaborare file XML che hanno un DTD con un XSLT in Java. Il DTD è davvero necessario perché contiene le definizioni delle entità che utilizzo. (a parte: sì, usare le entità per cose che potrebbero usare l'unicode è una cattiva idea ;-)Previene il download DTD quando si utilizza XSLT, ad esempio il trasformatore XML

Quando eseguo la trasformazione scarica ogni volta il DTD dalla sorgente esterna. Voglio che utilizzare un catalogo XML per memorizzare nella cache i DTD così ho dato il TransformerFactory un CatalogResolver come URIResolver:

URIResolver cr = new CatalogResolver(); 
tf = TransformerFactory.newInstance(); 
tf.setURIResolver(cr); 
Transformer t = tf.newTransformer(xsltSrc); 
t.setURIResolver(cr); 
Result res = new SAXResult(myDefaultHandler()); 
t.transform(xmlSrc, res); 

Ma quando ho eseguito la trasformazione che scarica ancora i DTD attraverso la rete. (Uso di Xalan e Xerces come parte di Java5 o autonomo o utilizzando Saxon e Xerces.)

Cosa serve per forzare la trasformazione a utilizzare solo la copia locale dei DTD?

risposta

10

(sto rispondendo alla mia domanda proprio qui per salvare me la prossima volta, o chiunque altro, i giorni di armeggiare avevo bisogno di trovare la risposta.)

Ciò che ha davvero bisogno di cambiare il modo in cui sono DTD risolto è un EntityResolver. Sfortunatamente non è possibile impostare EntityResolver per essere utilizzato da Transformer. Quindi bisogna creare un XMLReader prima con la CatalogResolver come EntityResolver:

SAXParserFactory spf = SAXParserFactory.newInstance(); 
spf.setNamespaceAware(true); 
XMLReader r = spf.newSAXParser().getXMLReader(); 
EntityResolver er = new CatalogResolver(); 
r.setEntityResolver(er); 

e utilizzarlo in per il Transformer:

SAXSource s = new SAXSource(r, xmlSrc); 
Result res = new SAXResult(myDefaultHandler()); 
transformer.transform(s, res); 
+0

+1 per risolvere da soli e condividere il risultato (al contrario di eliminare la domanda, che ho visto anche). – Tomalak

3

È possibile utilizzare questo codice per disattivare questo tipo di funzionalità in Xerces :

campione
org.dom4j.io.SAXReader reader = new org.dom4j.io.SAXReader(); 
reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 

Questo codice utilizza DOM4J, ma simile funzionalità "setFeature" esiste in altri libra Java XML ries come JDOM.

+1

http://xerces.apache.org/xerces2-j/features.html presentano queste funzionalità, a quanto pare. – PypeBros

Problemi correlati