简体   繁体   English

禁用基于外部 DTD/XSD 的 XML 验证

[英]Disable XML validation based on external DTD/XSD

Is there a way to disable XML validation based on external DTD/XSD without modifications to the source code (of the libraries that construct DocumentBuilder)?有没有一种方法可以禁用基于外部 DTD/XSD 的 XML 验证,而无需修改源代码(构建 DocumentBuilder 的库)? Something like setting JVM-wide defaults for DocumentBuilderFactory features, and the same for SAX?类似于为 DocumentBuilderFactory 功能设置 JVM 范围的默认值,对 SAX 也一样?

Validation is great when editing files in IDE, but I don't need my webapp failing to start just because somelib.net went down.在 IDE 中编辑文件时,验证非常有用,但我不需要我的 webapp 因为 somelib.net 出现故障而无法启动。

I know I can specify local DTD/XSD locations, but that's an inconvenient workaround.我知道我可以指定本地 DTD/XSD 位置,但这是一个不方便的解决方法。

What are the options?有什么选择? I can think of two:我能想到两个:

  • Implement my own DocumentBuilderFactory.实现我自己的 DocumentBuilderFactory。
  • Intercept construction of Xerces's DocumentBuilderImpl and modify the features Hashtable (add http://apache.org/xml/features/nonvalidating/load-external-dtd ).拦截 Xerces 的 DocumentBuilderImpl 的构造并修改features Hashtable(添加http://apache.org/xml/features/nonvalidating/load-external-dtd )。

Disabling validation may not prevent a processor from fetching a DTD, as it still may do so in order to use attribute defaults etc. present in the DTD (which it will place in the tree), even if it does no actual validation against the DTD's grammar.禁用验证可能不会阻止处理器获取 DTD,因为它仍然可以这样做以使用 DTD 中存在的属性默认值等(它将放置在树中),即使它没有针对 DTD 的实际验证语法。

One technique to prevent network activity when processing an XML document is to use a "blanking resolver" like this:处理 XML 文档时防止网络活动的一种技术是使用如下“消隐解析器”:

import java.io.ByteArrayInputStream;
import java.io.IOException;

import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class BlankingResolver implements EntityResolver
{

    public InputSource resolveEntity( String arg0, String arg1 ) throws SAXException,
            IOException
    {

        return new InputSource( new ByteArrayInputStream( "".getBytes() ) );
    }

}

and then set this prior to processing like this:然后在处理之前设置它,如下所示:

DocumentBuilderFactory factory = DocumentBuilderFactory.
factory.setNamespaceAware( true );
builder = factory.newDocumentBuilder();
builder.setEntityResolver( new BlankingResolver() );
myDoc = builder.parse( myDocUri );
// etc.

You will then also be sure that the document being processed has not been altered by any information from the DTD.y然后,您还将确保正在处理的文档没有被来自 DTD.y 的任何信息更改

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM