2009-01-22 6 views
8

J'ai un fichier XML sans déclaration DOCTYPE que je voudrais valider avec une DTD externe lors de la lecture..NET: Comment valider un fichier XML avec DTD sans déclaration DOCTYPE

Dim x_set As Xml.XmlReaderSettings = New Xml.XmlReaderSettings() 
x_set.XmlResolver = Nothing 
x_set.CheckCharacters = False 
x_set.ProhibitDtd = False 
x = XmlTextReader.Create(sChemin, x_set) 

Comment définir le chemin pour cette DTD externe? Comment validez-vous?

+0

return false; ;) –

Répondre

1

Pourriez-vous créer un Xml.XmlDocument avec la DTD souhaitée, puis ajouter les données du fichier XML dans le fichier Xml.XmlDocument en mémoire, puis valider cela?

15

J'ai déjà utilisé la fonction suivante avec succès, qui devrait être facile à adapter. Cependant, cela dépend de la création d'un XmlDocument comme magnifico mentionné. Ceci peut être réalisé par:

XmlDocument doc = new XmlDocument(); 
doc.Load(filename); 
doc.InsertBefore(doc.CreateDocumentType("doc_type_name", null, DtdFilePath, null), 
    doc.DocumentElement); 


/// <summary> 
/// Class to test a document against DTD 
/// </summary> 
/// <param name="doc">XML The document to validate</param> 
private static bool ValidateDoc(XmlDocument doc) 
{ 
    bool isXmlValid = true; 
    StringBuilder xmlValMsg = new StringBuilder(); 

    StringWriter sw = new StringWriter(); 
    doc.Save(sw); 
    doc.Save(TestFilename); 

    XmlReaderSettings settings = new XmlReaderSettings(); 
    settings.ProhibitDtd = false; 
    settings.ValidationType = ValidationType.DTD; 
    settings.ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings; 
    settings.ValidationEventHandler += new ValidationEventHandler(delegate(object sender, ValidationEventArgs args) 
    { 
     isXmlValid = false; 
     xmlValMsg.AppendLine(args.Message); 
    }); 

    XmlReader validator = XmlReader.Create(new StringReader(sw.ToString()), settings); 

    while(validator.Read()) 
    { 
    } 
    validator.Close(); 

    string message = xmlValMsg.ToString(); 
    return isXmlValid; 
} 
+0

Je voterais 20 fois si je le pouvais. Je me suis rapproché de SOOO mais c'est ce qu'il a fait. Merci! – CindyH

+0

Réponse vraiment utile. Pour ceux qui lisent ceci, la version la plus récente du framework .NET préfère settings.DtdProcessing = DtdProcessing.Parse au lieu de settings.ProhibidDtd = false. – artragis

+0

Donc, la solution est toujours que nous devons ajouter la chaîne DOCTYPE au début? Existe-t-il un moyen pour le code de pointer vers un emplacement externe non spécifié dans la chaîne DOCTYPE? –

-1
private static bool _isValid = true; 
static void Main(string[] args) 
{ 
    using (MemoryStream ms = new MemoryStream()) 
    { 
     using (FileStream file = new FileStream("C:\\MyFolder\\Product.dtd", FileMode.Open, FileAccess.Read)) 
     { 
      byte[] bytes = new byte[file.Length]; 
      file.Read(bytes, 0, (int) file.Length); 
      ms.Write(bytes, 0, (int) file.Length); 
     } 
     using (FileStream file = new FileStream("C:\\MyFolder\\Product.xml", FileMode.Open, FileAccess.Read)) 
     { 
      byte[] bytes = new byte[file.Length]; 
      file.Read(bytes, 0, (int) file.Length); 
      ms.Write(bytes, 0, (int) file.Length); 
     } 
     ms.Position = 0; 

     var settings = new XmlReaderSettings(); 
     settings.DtdProcessing = DtdProcessing.Parse; 
     settings.ValidationType = ValidationType.DTD; 
     settings.ValidationEventHandler += new ValidationEventHandler(OnValidationEvent); 
     var reader = XmlReader.Create(ms, settings); 

     // Parse the file. 
     while (reader.Read()) ; 
    } 
    // Check whether the document is valid or invalid. 
    if (_isValid) 
     Console.WriteLine("Document is valid"); 
    else 
     Console.WriteLine("Document is invalid"); 
} 

private static void OnValidationEvent(object obj, ValidationEventArgs args) 
{ 
    _isValid = false; 
    Console.WriteLine("Validation event\n" + args.Message); 
} 
+2

Votre réponse doit contenir une explication de votre code et une description de la façon dont il résout le problème. – AbcAeffchen

+0

Je ne pouvais pas trouver un moyen de valider xml par rapport à un document DTD externe. Dans mon cas, je reçois du XML à partir d'une socket tcp/ip et je veux le valider par rapport à un fichier DTD. L'exemple ci-dessus montre comment vous pouvez combiner une DTD et du code XML ensemble dans le même flux avant d'utiliser l'objet XmlReader pour effectuer la validation de la DTD. – Matt

Questions connexes