【问题标题】:.NET: Prevent XmlDocument.LoadXml from retrieving DTD.NET:防止 XmlDocument.LoadXml 检索 DTD
【发布时间】:2011-05-25 15:01:23
【问题描述】:

我有以下代码 (C#),它花费的时间太长并且抛出异常:

new XmlDocument().
LoadXml("<?xml version='1.0' ?><!DOCTYPE note SYSTEM 'http://someserver/dtd'><note></note>");

我明白为什么会这样。我的问题是如何让它停止?我不关心 DTD 验证。我想我可以用正则表达式替换它,但我正在寻找更优雅的解决方案。

背景:
实际的 XML 是从我不拥有的网站接收的。当站点进行维护时,它会返回带有 DOCTYPE 的 XML,该 XML 指向在维护期间不可用的 DTD。所以我的服务变得不必要的慢,因为它试图为我需要解析的每个 XML 获取 DTD。

这里是异常堆栈:

Unhandled Exception: System.Net.WebException: The remote name could not be resolved: 'someserver'
at System.Net.HttpWebRequest.GetResponse()
at System.Xml.XmlDownloadManager.GetNonFileStream(Uri uri, ICredentials credentials)
at System.Xml.XmlDownloadManager.GetStream(Uri uri, ICredentials credentials)
at System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
at System.Xml.XmlTextReaderImpl.OpenStream(Uri uri)
at System.Xml.XmlTextReaderImpl.DtdParserProxy_PushExternalSubset(String systemId, String publicId)
at System.Xml.XmlTextReaderImpl.DtdParserProxy.System.Xml.IDtdParserAdapter.PushExternalSubset(String systemId, String publicId)
at System.Xml.DtdParser.ParseExternalSubset()
at System.Xml.DtdParser.ParseInDocumentDtd(Boolean saveInternalSubset)
at System.Xml.DtdParser.Parse(Boolean saveInternalSubset)
at System.Xml.XmlTextReaderImpl.DtdParserProxy.Parse(Boolean saveInternalSubset)
at System.Xml.XmlTextReaderImpl.ParseDoctypeDecl()
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.XmlLoader.LoadDocSequence(XmlDocument parentDoc)
at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
at System.Xml.XmlDocument.Load(XmlReader reader)
at System.Xml.XmlDocument.LoadXml(String xml)
at ConsoleApplication36.Program.Main(String[] args) in c:\Projects\temp\ConsoleApplication36\Program.cs:line 11

【问题讨论】:

标签: .net xml dtd


【解决方案1】:

嗯,在 .NET 4.0 XmlTextReader 中有一个名为 DtdProcessing 的属性。当设置为 DtdProcessing.Ignore 时,它​​应该禁用 DTD 处理。

【讨论】:

  • 您应该尝试将 XmlReader.Settings.ValidationType 设置为 ValidationType.None。或者,我认为将 XmlReader.Settings.XmlResolver 设置为 null 也可以解决问题
【解决方案2】:

在 .net 4.5.1 中,我没有运气将 doc.XmlResolver 设置为 null。

对我来说最简单的解决方法是在调用 LoadXml() 之前使用字符串替换将“xmlns=”更改为“ignore=”,例如

var responseText = await response.Content.ReadAsStringAsync();
responseText = responseText.Replace("xmlns=", "ignore=");
try
{
    var doc = new XmlDocument();
    doc.LoadXml(responseText);
    ...
}

【讨论】:

    猜你喜欢
    • 2010-12-07
    • 1970-01-01
    • 2012-05-13
    • 2020-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    相关资源
    最近更新 更多