我获得了一个XML文档,必须允许其具有文档类型声明(DTD),但我们禁止任何ENTITY声明。
使用SAXParser.parse()
解析XML文档,如下所示:
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
factory.setValidating(true);
SAXParser parser = factory.newSAXParser();
然后将XML作为InputSource
:
InputSource inputSource= ... ;
parser.parse(inputSource, handler);
handler
有一个resolveEntity
方法,SAXParser.parse()
调用:
public InputSource resolveEntity(String pubID, String sysID) throws SAXException {
InputSource inputSource = null;
try {
inputSource = entityResolver.resolveEntity(publicId, systemId);
}
catch (IOException e) {
throw new SAXException(e);
}
return inputSource;
}
当我传入一个带有ENTITY引用的XML文件时,似乎没有做任何事情 - 没有抛出异常而且没有任何内容被剥离 - 与被禁止的ENTITY引用有关。
以下是我正在使用的错误XML的示例。应允许DTD,但不允许使用!ENTITY行:
<!DOCTYPE foo SYSTEM "foo.dtd" [
<!ENTITY gotcha SYSTEM "file:///gotcha.txt"> <!-- This is disallowed-->
]>
<label>&gotcha;</label>
我需要做些什么来确保XML中不允许使用ENTITY引用,但是仍然允许DTD?
答案 0 :(得分:2)
在SaxParser上设置org.xml.sax.ext.DeclHandler
。
parser.setProperty("http://xml.org/sax/properties/declaration-handler", myDeclHandler);
解析内部实体声明时会通知DeclHandler。要禁止实体decls,您可以简单地抛出SAXException:
public class MyDeclHandler extends org.xml.sax.ext.DefaultHandler2 {
public void internalEntityDecl(String name, String value) throws SAXException {
throw new SAXException("not allowed");
}
}