【发布时间】:2014-09-04 19:41:40
【问题描述】:
为什么下面SSCCE 中的非验证DocumentBuilder 试图读取DTD 文件?
public class FooMain {
private static String XML_INSTANCE = "<?xml version=\"1.0\"?> "+
"<!DOCTYPE note SYSTEM \"does-not-exist.dtd\"> "+
"<a/> ";
public static void main(String args[]) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(false);
factory.setValidating(false);
DocumentBuilder builder = factory.newDocumentBuilder();
InputStream is = new ByteArrayInputStream(XML_INSTANCE.getBytes("UTF-8"));
Document doc = builder.parse(is);
}
}
代码爆炸:
[java] Exception in thread "main" java.io.FileNotFoundException: /lhome/minimal-for-SO/does-not-exist.dtd (No such file or directory)
[java] at java.io.FileInputStream.open(Native Method)
[java] at java.io.FileInputStream.<init>(FileInputStream.java:146)
[java] at java.io.FileInputStream.<init>(FileInputStream.java:101)
[java] at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:90)
[java] at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:188)
[java] at org.apache.xerces.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
[java] at org.apache.xerces.impl.XMLEntityManager.startEntity(Unknown Source)
[java] at org.apache.xerces.impl.XMLEntityManager.startDTDEntity(Unknown Source)
[java] at org.apache.xerces.impl.XMLDTDScannerImpl.setInputSource(Unknown Source)
[java] at org.apache.xerces.impl.XMLDocumentScannerImpl$DTDDispatcher.dispatch(Unknown Source)
[java] at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
[java] at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
[java] at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
[java] at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
[java] at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
[java] at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
[java] at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:121)
[java] at FooMain.main(FooMain.java:35)
鉴于构建器未进行验证,如果找不到文件(如果不完全跳过对 DTD 文件的搜索),我希望至少不会崩溃。那么是什么阻止了文档被解析,因为构建器是非验证的,因此不需要访问 DTD?
【问题讨论】: