在JDOM / DOM中禁用XML实体解析

我正在编写一个用于XML文件后处理的Java应用程序。 这些xml文件来自Semantic Mediawiki的RDF-Export,因此它们具有rdf / xml语法。

我的问题如下:当我读取xml文件时,文件中的所有实体都被解析为其在Doctype中指定的值。 例如我在Doctype中

<!DOCTYPE rdf:RDF[  .. ]> 

并在根元素中

  

这意味着

  

  

我尝试过使用JDOM和标准Java DOM。 我认为这里的代码与标准DOM相关:

 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setExpandEntityReferences(false); factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 

并为JDOM

 SAXBuilder builder = new SAXBuilder(); builder.setExpandEntities(false); //Retain Entities builder.setValidation(false); builder.setFeature("http://xml.org/sax/features/resolve-dtd-uris", false); 

但是实体在整个xml文档中得到了解决。 我错过了什么吗? 几小时的搜索只引导我进入’ExpandEntities’命令,但它们似乎不起作用。

任何提示都非常感谢:)

我推荐JDOM FAQ:

[ http://www.jdom.org/docs/faq.html#a0350%5D

如何防止DTD加载? 即使我关闭validation,解析器也会尝试加载DTD文件。

即使关闭validation,XML解析器也会默认加载外部DTD文件,以便解析DTD以获取外部实体声明。 Xerces有一个function可以关闭名为“ http://apache.org/xml/features/nonvalidating/load-external-dtd ”的行为,如果您知道自己正在使用Xerces,则可以在构建器上设置此function。

 builder.setFeature( "http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 

如果你正在使用像Crimson这样的另一个解析器,你最好的办法是设置一个EntityResolver来解析DTD而不实际读取单独的文件。

 import org.xml.sax.*; import java.io.*; public class NoOpEntityResolver implements EntityResolver { public InputSource resolveEntity(String publicId, String systemId) { return new InputSource(new StringBufferInputStream("")); } } 

然后在建设者……

 builder.setEntityResolver(new NoOpEntityResolver()); 

这种方法有一个缺点。 文档中的任何实体都将被解析为空字符串,并且将有效消失。 如果您的文档包含实体,则需要设置ExpandEntities(false)代码并确保EntityResolver仅抑制DocType。

我相信如果validation(functionhttp://xml.org/sax/features/validation )为真,它会覆盖setExpandEntities(false) 。 尝试通过将该function设置为false来禁用validation。

我发现了各种类似的提示,表示你无法关闭属性中的实体扩展。 我不确定该说什么不丑。 例如,您可以使用EntityResolver来引入“null”DTD – 将“wiki”的扩展定义为“&wiki;”。 好像有更好的方法!