2009-07-07 7 views
7

Je dois traiter des fichiers XML qui ont une DTD avec un XSLT en Java. La DTD est vraiment nécessaire car elle contient les définitions des entités que j'utilise. (mis à part: oui, utiliser des entités pour des choses qui pourraient utiliser unicode est une mauvaise idée ;-)Empêcher le téléchargement de DTD lors de l'utilisation de XSLT, c'est-à-dire XML Transformer

Lorsque je lance la transformation, il télécharge la DTD depuis la source externe à chaque fois. Je veux utiliser un catalogue XML pour mettre en cache les DTD donc j'ai donné le TransformerFactory un CatalogResolver comme 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); 

Mais quand je lance la transformation qu'il télécharge toujours les DTD sur le réseau. (Utilisation de Xalan et de Xerces dans le cadre de Java5 ou autonome ou en utilisant Saxon et Xerces.)

Que faut-il pour forcer la transformation à utiliser uniquement la copie locale des DTD?

Répondre

10

(Je réponds à ma propre question ici pour me sauver la prochaine fois, ou quelqu'un d'autre, les jours de bricoler je devais trouver la réponse.)

Qu'est-ce qu'il a vraiment besoin de changer la façon dont sont DTDs résolu est un EntityResolver. Malheureusement, il n'est pas possible de définir le EntityResolver à utiliser par le Transformer. Donc, vous devez créer un XMLReader d'abord avec le CatalogResolver comme EntityResolver:

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

et l'utiliser dans le Transformer:

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

+1 pour avoir résolu le problème et partagé le résultat (par opposition à la suppression de la question, que j'ai également vue). – Tomalak

3

Vous pouvez utiliser ce code pour désactiver ce type de fonctionnalité dans Xerces :

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

Cet exemple de code utilise Dom4j, mais une fonctionnalité "setFeature" similaire existe dans d'autres bibliothèques XML java Ries tels que JDOM.

+1

http://xerces.apache.org/xerces2-j/features.html présentent ces caractéristiques, apparemment. – PypeBros

Questions connexes