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

Str*_*Bad 4 java xml parsing entity sax

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

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

<!DOCTYPE rdf:RDF[
<!ENTITY wiki 'http://example.org/smartgrid/index.php/Special:URIResolver/'>
..
]>
Run Code Online (Sandbox Code Playgroud)

并在根元素中

<rdf:RDF
xmlns:wiki="&wiki;"
..
>
Run Code Online (Sandbox Code Playgroud)

这意味着

<swivt:Subject rdf:about="&wiki;Main_Page">
Run Code Online (Sandbox Code Playgroud)

<swivt:Subject rdf:about="http://example.org/smartgrid/index.php/Special:URIResolver/Main_Page">
Run Code Online (Sandbox Code Playgroud)

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

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

并为JDOM

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

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

任何提示都非常感谢:)

小智 6

我推荐JDOM FAQ:

[ http://www.jdom.org/docs/faq.html#a0350]

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

即使关闭验证,XML解析器也会默认加载外部DTD文件,以便解析DTD以获取外部实体声明.Xerces有一个功能可以关闭这个名为" http://apache.org/xml/features/nonvalidating/load-external-dtd "的行为,如果你知道你正在使用Xerces,你可以在构建器上设置这个功能.

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

如果您正在使用另一个像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(""));
  }
}
Run Code Online (Sandbox Code Playgroud)

然后在建设者......

builder.setEntityResolver(new NoOpEntityResolver());
Run Code Online (Sandbox Code Playgroud)

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


Jim*_*son 0

我相信,如果验证(功能http://xml.org/sax/features/validation)为真,它将覆盖setExpandEntities(false). 还可以尝试通过将该功能设置为 来禁用验证false