Validation d’un code XML contre XSD référencé en C #

J’ai un fichier XML avec un emplacement de schéma spécifié tel que celui-ci:

xsi:schemaLocation="someurl ..\localSchemaPath.xsd" 

Je veux valider en C #. Visual Studio, lorsque j’ouvre le fichier, le valide avec le schéma et répertorie parfaitement les erreurs. D’une certaine manière, cependant, je n’arrive pas à le valider automatiquement en C # sans spécifier le schéma à valider comme ça:

 XmlDocument asset = new XmlDocument(); XmlTextReader schemaReader = new XmlTextReader("relativeSchemaPath"); XmlSchema schema = XmlSchema.Read(schemaReader, SchemaValidationHandler); asset.Schemas.Add(schema); asset.Load(filename); asset.Validate(DocumentValidationHandler); 

Ne devrais-je pas pouvoir valider automatiquement avec le schéma spécifié dans le fichier XML? Qu’est-ce que je rate ?

Vous devez créer une instance XmlReaderSettings et la transmettre à votre XmlReader lorsque vous le créez. Ensuite, vous pouvez vous abonner à ValidationEventHandler dans les parameters pour recevoir des erreurs de validation. Votre code finira par ressembler à ceci:

 using System.Xml; using System.Xml.Schema; using System.IO; public class ValidXSD { public static void Main() { // Set the validation settings. XmlReaderSettings settings = new XmlReaderSettings(); settings.ValidationType = ValidationType.Schema; settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema; settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation; settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings; settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack); // Create the XmlReader object. XmlReader reader = XmlReader.Create("inlineSchema.xml", settings); // Parse the file. while (reader.Read()) ; } // Display any warnings or errors. private static void ValidationCallBack(object sender, ValidationEventArgs args) { if (args.Severity == XmlSeverityType.Warning) Console.WriteLine("\tWarning: Matching schema not found. No validation occurred." + args.Message); else Console.WriteLine("\tValidation error: " + args.Message); } } 

Un moyen plus simple, si vous utilisez .NET 3.5, consiste à utiliser la validation XDocument et XmlSchemaSet .

 XmlSchemaSet schemas = new XmlSchemaSet(); schemas.Add(schemaNamespace, schemaFileName); XDocument doc = XDocument.Load(filename); ssortingng msg = ""; doc.Validate(schemas, (o, e) => { msg += e.Message + Environment.NewLine; }); Console.WriteLine(msg == "" ? "Document is valid" : "Document invalid: " + msg); 

Consultez la documentation MSDN pour plus d’assistance.

L’ exemple suivant valide un fichier XML et génère l’erreur ou l’avertissement approprié.

 using System; using System.IO; using System.Xml; using System.Xml.Schema; public class Sample { public static void Main() { //Load the XmlSchemaSet. XmlSchemaSet schemaSet = new XmlSchemaSet(); schemaSet.Add("urn:bookstore-schema", "books.xsd"); //Validate the file using the schema stored in the schema set. //Any elements belonging to the namespace "urn:cd-schema" generate //a warning because there is no schema matching that namespace. Validate("store.xml", schemaSet); Console.ReadLine(); } private static void Validate(Ssortingng filename, XmlSchemaSet schemaSet) { Console.WriteLine(); Console.WriteLine("\r\nValidating XML file {0}...", filename.ToSsortingng()); XmlSchema comstackdSchema = null; foreach (XmlSchema schema in schemaSet.Schemas()) { comstackdSchema = schema; } XmlReaderSettings settings = new XmlReaderSettings(); settings.Schemas.Add(comstackdSchema); settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack); settings.ValidationType = ValidationType.Schema; //Create the schema validating reader. XmlReader vreader = XmlReader.Create(filename, settings); while (vreader.Read()) { } //Close the reader. vreader.Close(); } //Display any warnings or errors. private static void ValidationCallBack(object sender, ValidationEventArgs args) { if (args.Severity == XmlSeverityType.Warning) Console.WriteLine("\tWarning: Matching schema not found. No validation occurred." + args.Message); else Console.WriteLine("\tValidation error: " + args.Message); } } 

L’exemple précédent utilise les fichiers d’entrée suivants.

    The Confidence Man 11.99   Americana Offspring 16.95   

books.xsd

                       

J’ai fait ce genre de validation automatique dans VB et c’est comme ça que je l’ai fait (converti en C #):

 XmlReaderSettings settings = new XmlReaderSettings(); settings.ValidationType = ValidationType.Schema; settings.ValidationFlags = settings.ValidationFlags | Schema.XmlSchemaValidationFlags.ProcessSchemaLocation; XmlReader XMLvalidator = XmlReader.Create(reader, settings); 

Puis je me suis abonné à l’événement settings.ValidationEventHandler lors de la lecture du fichier.

Personnellement, je suis en faveur de la validation sans rappel:

 public bool ValidateSchema(ssortingng xmlPath, ssortingng xsdPath) { XmlDocument xml = new XmlDocument(); xml.Load(xmlPath); xml.Schemas.Add(null, xsdPath); try { xml.Validate(null); } catch (XmlSchemaValidationException) { return false; } return true; } 

(voir l’article de Timiz0r dans Validation de schémas XML synchrones? .NET 3.5 )

Exemple MSDN utilisant LINQ to XML