使DocumentBuilder.parse忽略DTD引用

时间:2020-03-06 14:56:53  来源:igfitidea点击:

当我使用这种方法解析xml文件(变量f)时,出现错误

C:\Documents and Settings\joe\Desktop\aicpcudev\OnlineModule\map.dtd (The system cannot find the path specified)

我知道我没有dtd,也不需要它。如何在忽略DTD参考错误的同时将此File对象解析为Document对象?

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;
}

解决方案

I know I do not have the dtd, nor do I need it.

我对此说法表示怀疑;文档中是否包含任何实体引用?如果是这样,我们肯定需要DTD。

无论如何,防止这种情况发生的通常方法是使用XML目录为" map.dtd"定义本地路径。

这是另一个遇到相同问题的用户:http://forums.sun.com/thread.jspa?threadID=284209&forumID=34

该帖子上的用户ddssot说

myDocumentBuilder.setEntityResolver(new EntityResolver() {
          public InputSource resolveEntity(java.lang.String publicId, java.lang.String systemId)
                 throws SAXException, java.io.IOException
          {
            if (publicId.equals("--myDTDpublicID--"))
              // this deactivates the open office DTD
              return new InputSource(new ByteArrayInputStream("<?xml version='1.0' encoding='UTF-8'?>".getBytes()));
            else return null;
          }
});

用户进一步提到"如我们所见,当解析器命中DTD时,将调用实体解析器。我识别出具有特定ID的DTD并返回一个空的XML文档而不是真实的DTD,从而停止所有验证..."

希望这可以帮助。

与@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的一些文档。