使用XmlDocument.Load时,我发现如果文档引用DTD,则会与提供的URI建立连接.有没有办法防止这种情况发生?
经过一些挖掘,可能应该将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); }
正在加载的文档具有DTD.
附:
settings.ProhibitDtd = true;
我看到以下异常:
服务无法启动.System.Xml.XmlException:出于安全原因,此XML文档中禁止使用DTD.要启用DTD处理,请将XmlReaderSettings上的ProhibitDtd属性设置为false,并将设置传递给XmlReader.Create方法.
因此,在这种情况下看起来像ProhibitDtd必须设置为true.
看起来ValidationType可以解决问题,但是:
settings.ValidationType = ValidationType.None;
我仍然看到与DTD uri的连接.
这实际上是XML规范中的一个缺陷.W3C正在哀叹所有人都疯狂地点击他们的服务器来加载模式数十亿次.不幸的是,几乎没有标准的XML库能够做到这一点,它们都会一次又一次地击中服务器.
DTD的问题特别严重,因为DTD可能包含&
XML文件实际可能依赖的通用实体声明(例如- >&).因此,如果您的解析器选择放弃加载DTD,并且XML使用通用实体引用,则解析可能实际上失败.
此问题的唯一解决方案是透明缓存实体解析器,它将下载的文件放入库搜索路径中的某个存档中,以便该存档可以动态创建并几乎自动与任何软件分发捆绑在一起.但即使在Java世界中,也没有一个像这样的EntityResolver漂浮,当然也不是内置于apache基础的任何东西.