我必须使用Java中的XSLT处理具有DTD的XML文件。 DTD确实是必需的,因为它包含我使用的实体的定义。 (旁白:是的,使用实体来处理可能使用unicode的东西是一个坏主意; - )
当我运行转换时,它每次都会从外部源下载DTD。我希望它使用XML目录来缓存DTD,因此我将TransformerFactory
CatalogResolver
作为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);
但是当我运行转换时,它仍然通过网络下载DTD。 (使用Xalan和Xerces作为Java5的一部分或独立使用或使用Saxon和Xerces。)
强制转换只使用DTD的本地副本需要什么?
答案 0 :(得分:11)
(我在这里回答我自己的问题是为了救我下一次,或者其他任何人,我需要找到答案的修修日。)
改变DTD解决方式的真正需要是EntityResolver
。很遗憾,无法设置EntityResolver
要使用的Transformer
。因此,您必须首先使用XMLReader
CatalogResolver
创建EntityResolver
:
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
XMLReader r = spf.newSAXParser().getXMLReader();
EntityResolver er = new CatalogResolver();
r.setEntityResolver(er);
并将其用于Transformer
:
SAXSource s = new SAXSource(r, xmlSrc);
Result res = new SAXResult(myDefaultHandler());
transformer.transform(s, res);
答案 1 :(得分:3)
您可以使用此代码在Xerces中禁用此类功能:
org.dom4j.io.SAXReader reader = new org.dom4j.io.SAXReader();
reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
此代码示例使用Dom4j,但类似的“setFeature”功能存在于其他Java XML库(如JDOM)中。