Java 使DocumentBuilder.parse忽略DTD引用
当我用这个方法解析xml文件(变量f)时,我得到一个错误 C:\Documents and Settings\joe\Desktop\aicpcudev\OnlineModule\map.dtd(系统找不到指定的路径) 我知道我没有dtd,也不需要它。如何在忽略DTD引用错误的情况下将此文件对象解析为文档对象Java 使DocumentBuilder.parse忽略DTD引用,java,document,dtd,Java,Document,Dtd,当我用这个方法解析xml文件(变量f)时,我得到一个错误 C:\Documents and Settings\joe\Desktop\aicpcudev\OnlineModule\map.dtd(系统找不到指定的路径) 我知道我没有dtd,也不需要它。如何在忽略DTD引用错误的情况下将此文件对象解析为文档对象 private static Document getDoc(File f, String docId) throws Exception{ DocumentBuilderFact
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;
}
我知道我没有dtd,也不需要它
我对这种说法表示怀疑;您的文档是否包含任何实体引用?如果是这样,您肯定需要DTD
无论如何,防止这种情况发生的通常方法是使用XML目录为“map.dtd”定义本地路径 该帖子上的用户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;
}
});
myDocumentBuilder.setEntityResolver(新的EntityResolver(){
public InputSource resolveEntity(java.lang.String publicId,java.lang.String systemId)
抛出SAXException,java.io.IOException
{
if(publicId.equals(“--myDTDpublicID-->”)
//这将停用open office DTD
返回新的InputSource(新的ByteArrayInputStream(“.getBytes()”);
否则返回null;
}
});
用户进一步提到“正如您所看到的,当解析器点击DTD时,实体解析器被调用。我用它的特定ID识别我的DTD,并返回一个空的XML文档而不是真实的DTD,停止所有验证…”
希望这能有所帮助。类似于
我发现简单地返回一个空的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();
...
最后,我认为这些选项是特定于解析器实现的。如果有帮助的话。我发现一个问题,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;
}
}
});
源XML(带DTD)
目标XML(不带DTD)
1234567890
001
美元
201611100000777
我正在使用sonarqube,sonarlint for eclipse向我展示了不受信任的XML应该在不解析外部数据的情况下解析(squid:S2755)
我设法用以下方法解决了这个问题:
factory = DocumentBuilderFactory.newInstance();
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// If you can't completely disable DTDs, then at least do the following:
// Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-general-entities
// Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-general-entities
// JDK7+ - http://xml.org/sax/features/external-general-entities
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
// Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-parameter-entities
// Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-parameter-entities
// JDK7+ - http://xml.org/sax/features/external-parameter-entities
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
// Disable external DTDs as well
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
// and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks"
factory.setXIncludeAware(false);
factory.setExpandEntityReferences(false);
最后一个(
load external dtd
)帮了我的忙-谢谢。在尝试此操作时,我遇到了一个DomeException:NAMESPACE\u ERR:试图以一种不正确的方式创建或更改对象。。我用dbf.setNamespaceAware(true)修复了这个问题
让您知道,上一个功能设置(如@Amarghosh所述)在SAXParserFactory中非常有效。对我来说,加载外部dtd
设置就足够了。使用上述所有功能也会导致代码失败。仅使用最后两个功能(非验证)就可以使我的代码正常工作。在DocumentBuilderFactory上设置这些功能对我来说很有效。这篇文章中的解决方案不起作用。这对我来说也非常有效,尽管我认为我没有使用SAXS,但这对我来说不起作用。我还是犯了错误@jt为我做了这件事。谢谢你的解决方案,我认为这是org.xml推荐的方法。这方面的资料似乎很多。看,或者javadoc,我相信jt对这个问题有最好的答案。
<!DOCTYPE MYSERVICE SYSTEM "./MYSERVICE.DTD">
<MYACCSERVICE>
<REQ_PAYLOAD>
<ACCOUNT>1234567890</ACCOUNT>
<BRANCH>001</BRANCH>
<CURRENCY>USD</CURRENCY>
<TRANS_REFERENCE>201611100000777</TRANS_REFERENCE>
</REQ_PAYLOAD>
</MYACCSERVICE>
public Document removeDTDFromXML(String payload) throws Exception {
System.out.println("### Payload received in XMlDTDRemover: " + payload);
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
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();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(payload));
doc = db.parse(is);
} catch (ParserConfigurationException e) {
System.out.println("Parse Error: " + e.getMessage());
return null;
} catch (SAXException e) {
System.out.println("SAX Error: " + e.getMessage());
return null;
} catch (IOException e) {
System.out.println("IO Error: " + e.getMessage());
return null;
}
return doc;
}
<MYACCSERVICE>
<REQ_PAYLOAD>
<ACCOUNT>1234567890</ACCOUNT>
<BRANCH>001</BRANCH>
<CURRENCY>USD</CURRENCY>
<TRANS_REFERENCE>201611100000777</TRANS_REFERENCE>
</REQ_PAYLOAD>
</MYACCSERVICE>
factory = DocumentBuilderFactory.newInstance();
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// If you can't completely disable DTDs, then at least do the following:
// Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-general-entities
// Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-general-entities
// JDK7+ - http://xml.org/sax/features/external-general-entities
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
// Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-parameter-entities
// Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-parameter-entities
// JDK7+ - http://xml.org/sax/features/external-parameter-entities
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
// Disable external DTDs as well
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
// and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks"
factory.setXIncludeAware(false);
factory.setExpandEntityReferences(false);