禁止实体声明但允许DTD

时间:2015-07-08 20:20:04

标签: java xml sax saxparser

我获得了一个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?

1 个答案:

答案 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");
     }
}