2009-10-02 13 views
5

Je triying pour valider un fichier XML. J'utilise ce codevalidation de problème un fichier XML avec un fichier DTD local 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(); 

Mais dans la ligne "reader.Settings.Schemas.Add (null, lblDTDPath.Text);" Visual Studio me montre cette erreur "Pour des raisons de sécurité DTD est interdite dans ce document XML Pour activer le traitement DTD, définissez la propriété ProhibitDtd sur XmlReaderSettings sur false et transmettez les paramètres dans la méthode XmlReader.Create"

Comme vous pouvez le voir dans le code, ProhibitDtd est défini sur false (j'ai vérifié pendant le débogage aussi). J'ai également essayé d'ajouter le schéma avant l'appel à XmlReader.Create() sans succès.

Répondre

0

De mon farfouillé la seule façon que je pourrais le faire fonctionner est de ne pas ajouter le schéma à l'XmlReader. La DTD spécifiée dans le document XML doit être une URL valide et la XmlReader téléchargera chaque fois.

Si vous avez besoin du shema être local, vous pouvez modifier l'URL de la DTD pour pointer vers un fichier local en utilisant une expression régulière de sorte qu'il regarderait somthing comme

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

Notez le fichier : dans l'url. Faites-le en mémoire avant de le passer à XmlReader et de cette façon vous n'avez pas besoin de modifier le fichier xml juste pour varifier que c'est correct.

+0

mais je veux l'utilisateur pour sélectionner à partir du HD les deux fichiers, le XML et le dtd, et lui dire si le XML est valide ou non. Je suis assez sûr que cela peut être fait, mais je ne sais pas comment: – Jonathan

+0

Mis à jour mon aswer avec une solution possible pour charger la DTD à partir d'un fichier local – Geoff

0

Essayez d'ajouter à votre schéma DTD à la collecte des schémas avant l'appel à XmlReader.Create.

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

J'ai également essayé ir avant (et maintenant encore) sans J'obtiens la même erreur C'est un peu frustrant xD – Jonathan

+0

@Johnathan Peut-être, après avoir créé votre XmlReader (dans votre exemple original ci-dessus), vérifiez la valeur de ** XmlReader.Settings.ProhibitDtd ** et voyez si c'est vraiment faux ? De votre question, je ne suis pas sûr si c'était la valeur que vous étiez en train de vérifier, ou la valeur sur les paramètres initiaux.ProhibitDtd. Assurez-vous juste qu'ils montrent la même valeur.Si le lecteur ne, essayez de le mettre à ? false avant le chargement de vos schémas vous avez probablement déjà essayé, mais il n'y a rien d'autre qui ressemble à cela pourrait même être un problème –

+1

@ Jonathan: avez-vous réussi à obtenir ce fait de travailler avec un fichier .dtd Je ne? Je pense que XmlSchemaSet peut être utilisé avec un fichier .dtd file ... Seuls les fichiers .xsd.Je continue d'obtenir ce message d'erreur, peu importe ce que j'essaie. – fretje

0

J'ai eu un problème similaire. La réponse, pour moi, était que la DTD n'a pas besoin d'être connectée via les schémas comme le montre le fichier XML, l'ajout via les schémas m'a causé le problème.

+0

Je vais essayer dès que possible. Merci. – Jonathan

2

Je l'ai fait un certain temps avant de valider les flux RSS. La méthode pour faire la validation par DTD stocké localement est d'insérer une coutume XmlResolver à la XmlReader

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

qui donne au lecteur la DTD locale (pour les formats connus) au lieu de le télécharger à partir de l'URL donnée dans DOCTYPE.

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); 
    } 
} 

Comme une note finale, j'ai décidé de ne pas utiliser la validation DTD à la fin et aller pour la validation par schéma XML, l'une des raisons étant que de nombreux aliments ne comprenaient pas le DOCTYPE