2010-12-14 11 views
11

Mam następujący kod (C#), trwa zbyt długo i rzuca wyjątek:NET: Zapobiegać XmlDocument.LoadXml od pobierania DTD

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

rozumiem, dlaczego to robi. Moje pytanie brzmi: jak mogę to zatrzymać? Nie dbam o sprawdzanie DTD. Przypuszczam, że mógłbym po prostu je zastąpić, ale szukam bardziej eleganckiego rozwiązania.

Tło:
Rzeczywisty kod XML pochodzi z witryny internetowej, której nie jestem właścicielem. Kiedy serwis jest w trakcie konserwacji, zwraca XML z DOCTYPE, który wskazuje na DTD, który nie jest dostępny podczas konserwacji. Moja usługa staje się niepotrzebnie powolna, ponieważ próbuje uzyskać definicję DTD dla każdego pliku XML, który należy przeanalizować.

Oto wyjątek stosu:

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 

Odpowiedz

10

Cóż, w .NET 4.0 XmlTextReader ma właściwość o nazwie DtdProcessing. Po ustawieniu na DtdProcessing.Ignore powinno wyłączyć przetwarzanie DTD.

+0

co powiecie na .net 3.5? –

+0

Powinieneś spróbować ustawić XmlReader.Settings.ValidationType na ValidationType.None. Alternatywnie, myślę, że ustawienie XmlReader.Settings.XmlResolver na wartość null również może zdziałać. –

+13

Potwierdzone 'doc.XmlResolver = null;' rozwiązuje problem. –

0

W .net 4.5.1 Nie miałem szczęścia ustawiania doc.XmlResolver na wartość null.

Najprostszym rozwiązaniem dla mnie było użycie zamiany ciągów znaków w celu zmiany "xmlns =" ​​na "ignore =" przed wywołaniem LoadXml(), np.

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