使DocumentBuilder.parse忽略DTD引用
当我在这个方法中解析我的xml文件(变量f)时,出现错误
C: Documents and Settings joe Desktop aicpcudev OnlineModule map.dtd(系统找不到指定的路径)
我知道我没有dtd,也不需要它。 我该如何解析这个File对象到一个Document对象中而忽略DTD引用错误?
private static Document getDoc(File f, String docId) throws Exception{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(f);
return doc;
}
类似于@anjanb提出的方法
builder.setEntityResolver(new EntityResolver() {
@Override
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException, IOException {
if (systemId.contains("foo.dtd")) {
return new InputSource(new StringReader(""));
} else {
return null;
}
}
});
我发现简单地返回一个空的InputSource也工作得很好?
尝试在DocumentBuilderFactory上设置功能:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
dbf.setNamespaceAware(true);
dbf.setFeature("http://xml.org/sax/features/namespaces", false);
dbf.setFeature("http://xml.org/sax/features/validation", false);
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
DocumentBuilder db = dbf.newDocumentBuilder();
...
最终,我认为这些选项是特定于解析器实现的。 如果有帮助,这里是Xerces2的一些文档。
我发现DTD文件与XML一起位于jar文件中。 我基于这里的例子解决了这个问题,如下所示: -
DocumentBuilder db = dbf.newDocumentBuilder();
db.setEntityResolver(new EntityResolver() {
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
if (systemId.contains("doc.dtd")) {
InputStream dtdStream = MyClass.class
.getResourceAsStream("/my/package/doc.dtd");
return new InputSource(dtdStream);
} else {
return null;
}
}
});
链接地址: http://www.djcxy.com/p/34903.html