我想读取一个在其中有一个模式声明的
XML文件.
这就是我想做的,读它.我不在乎它是否有效,但我希望它形成良好.
问题是读者试图读取模式文件,并且失败.
我不想让它甚至尝试.
我已经尝试禁用验证,但它仍然坚持尝试读取模式文件.
理想情况下,我想用一个Java 5 JDK库存来实现.
这是我到目前为止,很简单:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setValidating(false); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(file);
这是我回来的例外:
java.lang.RuntimeException: java.io.IOException: Server returned HTTP response code: 503 for URL: http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
是的,这个HAPPENS是一个XHTML模式,但这不是一个“XHTML”问题,这是一个XML问题.只是指出,所以人们不会分心.而在这种情况下,W3C基本上就是说“不要求这件事,这是一个愚蠢的想法”,我同意.但是,这又是一个问题的细节,而不是它的根源.我不想要求所有.
解决方法
引用不是针对模式,而是用于DTD.
DTD文件不仅可以包含结构规则.它们还可以包含实体引用. XML解析器有义务加载和解析DTD引用,因为它们可能包含可能影响文档解析的实体引用和文件的内容(您可以为文本或甚至整个短语的实体引用).
如果您想避免加载和解析引用的DTD,you can provide your own 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; } } });