2009-07-07 15 views
7

Muszę przetwarzać pliki XML, które mają DTD z XSLT w Javie. DTD jest naprawdę potrzebny, ponieważ zawiera definicje podmiotów, których używam. (poza: tak, używanie obiektów dla rzeczy, które mogą używać unicode, jest złym pomysłem ;-)Zapobieganie pobieraniu DTD podczas używania XSLT, tj. XML Transformer

Po uruchomieniu transformacji pobiera DTD ze źródła zewnętrznego za każdym razem. Chcę go użyć katalogu XML do buforować DTD więc dałem TransformerFactoryCatalogResolver jak 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); 

Ale kiedy uruchomić transformację nadal pobiera DTD przez sieć. (Używanie Xalan i Xerces jako części Java5 lub samodzielnej lub przy użyciu Saxona i Xerces.)

Co trzeba zrobić, aby wymusić transformację, aby używać tylko lokalnej kopii DTD?

Odpowiedz

10

(mam odpowiedzi na moje własne pytanie tutaj, aby zaoszczędzić mi następnym razem, czy ktokolwiek inny, dni majsterkowania Musiałem znaleźć odpowiedź.)

Co to naprawdę musi zmienić sposób DTD są rozwiązany to EntityResolver. Niestety nie można ustawić wartości EntityResolver, która ma być używana przez Transformer. Więc trzeba stworzyć XMLReader najpierw z CatalogResolver jak jego EntityResolver:

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

i używać go w za Transformer:

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

+1 za samodzielne rozwiązanie i udostępnienie wyniku (w przeciwieństwie do usunięcia pytania, które również widziałem). – Tomalak

3

Można użyć tego kodu do wyłączenia tego rodzaju funkcjonalność w Xerces :

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

Ten przykładowy kod używa Dom4j, ale podobna funkcjonalność "setFeature" istnieje w innych libra Java java takie jak JDOM.

+1

http://xerces.apache.org/xerces2-j/features.html najwyraźniej przedstawiają te funkcje. – PypeBros

Powiązane problemy