2009-07-07 6 views
7

Tengo que procesar los archivos XML que tienen una DTD con un XSLT en Java. La DTD es realmente necesaria porque contiene las definiciones de las entidades que uso. (a un lado: sí, usar entidades para cosas que podrían usar unicode es una mala idea ;-)Evitar la descarga de DTD cuando se utiliza XSLT, es decir, XML Transformer

Cuando ejecuto la transformación, descargo el DTD de la fuente externa todo el tiempo. Quiero que se utilice un catálogo XML para almacenar en caché los DTD así que me dio la TransformerFactory un CatalogResolver como 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); 

Pero cuando corro la transformación que sigue descarga los DTD través de la red. (Usando Xalan y Xerces como parte de Java5 o independiente o usando Saxon y Xerces.)

¿Qué se necesita para forzar la transformación para usar solo la copia local de los DTD?

Respuesta

10

(estoy respondiendo a mi propia pregunta, para salvarme la próxima vez, o cualquier otra persona, los días de retoques que necesita para encontrar la respuesta.)

Lo que realmente se necesita para cambiar la forma en que son DTD resuelto es un EntityResolver. Desafortunadamente no es posible configurar el EntityResolver para ser utilizado por el Transformer. Así que hay que crear un XMLReader primero con el CatalogResolver como su EntityResolver:

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

y lo utiliza en la Transformer:

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

+1 para resolver por su cuenta y compartir el resultado (en lugar de eliminar la pregunta, que también he visto). – Tomalak

3

Usted puede utilizar este código para desactivar este tipo de funcionalidad en Xerces :

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

Este ejemplo de código usa Dom4j, pero existe una funcionalidad similar "setFeature" en otra libra XML de Java como JDOM.

+1

http://xerces.apache.org/xerces2-j/features.html presentan esas características, al parecer. – PypeBros

Cuestiones relacionadas