我想读取一个包含模式声明的XML文件.
这就是我想做的一切,请阅读.我不在乎它是否有效,但我希望它形成良好.
问题是读者正在尝试读取模式文件,并且失败了.
我甚至不想尝试.
我已经尝试禁用验证,但它仍然坚持尝试读取模式文件.
理想情况下,我想用库存Java 5 JDK来做这件事.
这是我到目前为止所做的,非常简单:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
Run Code Online (Sandbox Code Playgroud)
这是我回来的例外:
java.lang.RuntimeException: java.io.IOException: Server returned HTTP response code: 503 for URL: http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
Run Code Online (Sandbox Code Playgroud)
是的,这个HAPPENS是一个XHTML模式,但这不是一个"XHTML"问题,它是一个XML问题.只是指出这一点,所以人们不会分心.并且,在这种情况下,W3C基本上是在说"不要求这个东西,这是一个愚蠢的想法",我同意.但是,这又是问题的细节,而不是问题的根源.我不想要求它.
Mad*_*sen 14
引用不是针对Schema,而是针对DTD.
DTD文件不仅包含结构规则.它们还可以包含实体引用.XML解析器有义务加载和解析DTD引用,因为它们可能包含可能影响文档解析方式的实体引用和文件内容(您可以为字符甚至整个文本短语提供实体引用).
如果您想要避免加载和解析引用的DTD,您可以提供自己的EntityResolver并测试引用的DTD,并决定是加载DTD文件的本地副本还是仅返回null.
自定义EntityResolvers上引用答案的代码示例:
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;
}
}
});
Run Code Online (Sandbox Code Playgroud)
jpa*_*kal 10
最简单的答案是这个单行程序,在创建DocumentBuilderFactory后调用:
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
Run Code Online (Sandbox Code Playgroud)
从Make DocumentBuilder.parse无耻地抄袭忽略DTD引用.