2009-10-02 11 views
5

Ich bin triying, um eine XML-Datei zu validieren. Ich verwende diesen CodeProblem Validierung einer XML-Datei mit einer lokalen DTD-Datei in C#

XmlReaderSettings settings = new XmlReaderSettings(); 
settings.ProhibitDtd = false; 
settings.ValidationType = ValidationType.DTD; 

settings.ValidationEventHandler += new ValidationEventHandler(validationError);   

XmlSchemaSet schemas = new XmlSchemaSet(); 
settings.Schemas = schemas; 
XmlReader reader = XmlReader.Create(lblXmlPath.Text, settings); 

reader.Settings.Schemas.Add(null, lblDTDPath.Text); 
while (reader.Read()) 
{ 
      // empty by now 
} 
reader.Close(); 

Aber in der Zeile "reader.Settings.Schemas.Add (null, lblDTDPath.Text);" Visual Studio zeigt mir diesen Fehler "Aus Sicherheitsgründen ist DTD in diesem XML-Dokument verboten. Um die DTD-Verarbeitung zu aktivieren, setzen Sie die ProhibitDtd-Eigenschaft auf XmlReaderSettings auf false und übergeben Sie die Einstellungen in XmlReader.Create-Methode"

Wie Sie in der Code, ProhibitDtd wird auf false gesetzt (ich habe das auch während des Debugs verifiziert). Ich habe auch versucht, das Schema vor Aufruf an XmlReader.Create() ohne Erfolg hinzuzufügen.

Antwort

0

Von meinem stochern um die einzige Möglichkeit, ich könnte es zur Arbeit zu bringen ist nicht das Schema zu der XmlReader hinzuzufügen. Die im XML-Dokument angegebene DTD muss eine gültige URL sein und die XmlReader wird jedes Mal herunterladen.

Wenn Sie die shema als lokal benötigen, können Sie die URL der DTD ändern, um eine lokale Datei zeigen einen regulären Ausdruck, so dass es ungefähr wie

<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.3//EN" "file:C:\wml.dtd"> 

Hinweis die Datei aussehen: in der URL. Führen Sie dies im Speicher aus, bevor Sie es an den XmlReader übergeben. Auf diese Weise müssen Sie die XML-Datei nicht ändern, nur um zu bestätigen, dass sie korrekt ist.

+0

aber ich den Benutzer Wählen Sie aus der HD beide Dateien, die XML und die dtd, und sagen Sie ihm, ob die XML gültig ist oder nicht. Ich bin ziemlich sicher, dass es getan werden kann, aber ich weiß nicht wie :( – Jonathan

+0

Aktualisiert meine Antwort mit einer möglichen Lösung, um die DTD von einer lokalen Datei zu laden. – Geoff

0

Versuchen Sie, vor dem Aufruf von XmlReader.Create zu Ihrem DTD-Schema eine Schemasammlung hinzuzufügen.

XmlReaderSettings settings = new XmlReaderSettings(); 
settings.ProhibitDtd = false; 
settings.ValidationType = ValidationType.DTD; 

settings.ValidationEventHandler += new ValidationEventHandler(validationError);   

XmlSchemaSet schemas = new XmlSchemaSet(); 

schemas.Add(null, lblDTDPath.Text); 
settings.Schemas = schemas; 

XmlReader reader = XmlReader.Create(lblXmlPath.Text, settings); 

while (reader.Read()) 
{ 
      // empty by now 
} 
reader.Close(); 
+0

Ich habe auch ir vor (und jetzt wieder) mit Nein versucht Ich bekomme den gleichen Fehler.Es ist ein wenig frustrierend xD – Jonathan

+0

@Johnathan Vielleicht, nach dem Erstellen Ihrer XmlReader (in Ihrem ursprünglichen Beispiel oben), überprüfen Sie den Wert von ** XmlReader.Settings.ProhibitDtd ** und sehen, ob es wirklich falsch ist ? Von Ihrer Frage bin ich nicht sicher, ob das der Wert war, den Sie prüften, oder der Wert auf den Anfangseinstellungen. ProhibitDtd. Stellen Sie einfach sicher, dass sie den gleichen Wert zeigen. Wenn der Leser nicht, versuchen Sie es zu setzen false, bevor Sie Ihre Schemas geladen haben? Sie haben es wahrscheinlich schon ausprobiert, aber es gibt nichts, was so aussehen könnte, als wäre es ein Problem? –

+1

@Jonathan: Haben Sie es tatsächlich geschafft, dies mit einer .dtd-Datei zu erledigen? t Think XmlSchemaSet kann mit einem .dtd verwendet werden Datei ... Nur .xsd Dateien.Ich bekomme immer diese Fehlermeldung, egal was ich versuche. – fretje

0

Ich hatte ein ähnliches Problem. Die Antwort für mich war, dass die DTD nicht über die Schemas verbunden werden muss, da die XML-Datei nach außen zeigt, und das Hinzufügen von Schemas hat mir das Problem verursacht.

+0

Ich werde es so bald wie möglich versuchen. Vielen Dank. – Jonathan

2

Ich habe dies vor einiger Zeit für die Validierung von RSS-Feeds getan. Die Methodenvalidierung zu tun DTD durch lokal gespeichert war ein benutzerdefinierte XmlResolver zum XmlReader

XmlReaderSettings readerSettings = new XmlReaderSettings(); 
readerSettings.ValidationType = ValidationType.DTD; 
readerSettings.ProhibitDtd = false; 
readerSettings.XmlResolver = new XmlFakeDtdResolver(); 

einzufügen, die dem Leser der lokalen DTD (für bekannte Formate) geben würden, anstatt es aus der URL angegeben in DOCTYPE herunterzuladen.

class XmlFakeDtdResolver : XmlUrlResolver 
{ 
    public static Dictionary<Uri, byte[]> dtdMap = new Dictionary<Uri, byte[]>(); 
    public static Dictionary<string, Uri> uriMap = new Dictionary<string, Uri>(); 
    static XmlFakeDtdResolver() 
    { 
     Uri rss091uri = new Uri("http://fake.uri/rss091"); 
     uriMap["-//Netscape Communications//DTD RSS 0.91//EN"] = rss091uri; 
     uriMap["http://my.netscape.com/publish/formats/rss-0.91.dtd"] = rss091uri; 
     dtdMap[rss091uri] = Encoding.ASCII.GetBytes(Resources.rss_0_91dtd); 
    } 

    public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn) 
    { 
     if (dtdMap.ContainsKey(absoluteUri) && ofObjectToReturn == typeof(Stream)) 
     { 
      return new MemoryStream(dtdMap[absoluteUri]); 
     } 
     return base.GetEntity(absoluteUri, role, ofObjectToReturn); 
    } 

    public override Uri ResolveUri(Uri baseUri, string relativeUri) 
    { 
     if (uriMap.ContainsKey(relativeUri)) 
      return uriMap[relativeUri]; 
     return base.ResolveUri(baseUri, relativeUri); 
    } 
} 

Als Endnote, entschied ich mich nicht in der End-DTD-Validierung zu verwenden und für die Validierung von XML-Schema, ein Grund gehen wollen, ist, dass viele Feeds sind nicht die DOCTYPE

Verwandte Themen