使用XSLT即XML Transformer时防止DTD下载

时间:2009-07-07 09:50:27

标签: java xml xslt

我必须使用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的本地副本需要什么?

2 个答案:

答案 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)中。