2008-10-19 184 views
30

使用XmlDocument.Load时,我发现如果文档引用DTD,则会与提供的URI建立连接。有什么办法可以防止这种情况发生?解析XML时防止DTD下载

回答

31

经过一些挖掘,也许你应该设置XmlReaderSettings对象的XmlResolver属性为null。

“的的XmlResolver用于定位和 打开XML实例文档,或者 找到并打开由XML实例文档 引用的任何外部资源 。这可以包括实体, DTD或模式。'

因此,代码是这样的:

 XmlReaderSettings settings = new XmlReaderSettings(); 
     settings.XmlResolver = null; 
     settings.DtdProcessing = DtdProcessing.Parse; 
     XmlDocument doc = new XmlDocument(); 
     using (StringReader sr = new StringReader(xml)) 
      using (XmlReader reader = XmlReader.Create(sr, settings)) 
      { 
       doc.Load(reader); 
      } 
1

使用XMLReader加载文档并将ValidationType读取器设置的属性设置为None

+1

不幸的是,如果XML使用DTD中定义的实体引用,那么不幸的是,因为这会导致XML格式不正确,而且无效。 – 2008-10-19 05:59:31

+0

所以,我仍然觉得有必要处理DTD以正确处理实体引用。这在没有连接的情况下如何工作? – spender 2008-10-19 12:00:42

2

尝试是这样的:

XmlDocument doc = new XmlDocument(); 
using (StringReader sr = new StringReader(xml)) 
    using (XmlReader reader = XmlReader.Create(sr, new XmlReaderSettings())) 
    { 
    doc.Load(reader); 
    } 

这里要注意的一点是,XmlReaderSettings有ProhibitDtd属性默认设置为true。

5

正在加载的文件有一个DTD。

有了:

settings.ProhibitDtd = true; 

我看到以下异常:

服务无法启动。 System.Xml.XmlException:出于安全原因,此XML文档中禁止使用DTD。要启用DTD处理,请将XmlReaderSettings上的ProhibitDtd属性设置为false,并将设置传递给XmlReader.Create方法。

因此,它看起来像ProhibitDtd务必在这种情况下设置为true。

它看起来像ValidationType会做的伎俩,但:

settings.ValidationType = ValidationType.None; 

我仍然看到的DTD的URI的连接。

5

这实际上是在XML规范的缺陷。 W3C很遗憾,人们都疯狂地把他们的服务器打到数十亿次。不幸的是,几乎没有标准的XML库能够正确使用它们,它们都一次又一次地重复着服务器。

DTD的问题尤其严重,因为DTD可能包括一般实体声明(对于像& - > &这类XML文件实际上可能依赖的东西)。因此,如果您的解析器选择放弃加载DTD,并且XML使用一般实体引用,则解析可能实际上失败。

此问题的唯一解决方案是透明缓存实体解析器,它将下载的文件放入库搜索路径中的某个存档中,以便该存档将动态创建并几乎自动与任何软件分发捆绑在一起。但即使在Java世界中,也没有一个像这样的EntityResolver漂浮的,当然不是内置于任何来自Apache基础的东西。