validate validar error con c# xml xsd

error - Validar un XML contra XSD referenciado en C#



xml validate xsd c# (6)

El siguiente example valida un archivo XML y genera el error o advertencia apropiado.

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(String filename, XmlSchemaSet schemaSet) { Console.WriteLine(); Console.WriteLine("/r/nValidating XML file {0}...", filename.ToString()); XmlSchema compiledSchema = null; foreach (XmlSchema schema in schemaSet.Schemas()) { compiledSchema = schema; } XmlReaderSettings settings = new XmlReaderSettings(); settings.Schemas.Add(compiledSchema); 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); } }

El ejemplo anterior usa los siguientes archivos de entrada.

<?xml version=''1.0''?> <bookstore xmlns="urn:bookstore-schema" xmlns:cd="urn:cd-schema"> <book genre="novel"> <title>The Confidence Man</title> <price>11.99</price> </book> <cd:cd> <title>Americana</title> <cd:artist>Offspring</cd:artist> <price>16.95</price> </cd:cd> </bookstore>

books.xsd

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:bookstore-schema" elementFormDefault="qualified" targetNamespace="urn:bookstore-schema"> <xsd:element name="bookstore" type="bookstoreType"/> <xsd:complexType name="bookstoreType"> <xsd:sequence maxOccurs="unbounded"> <xsd:element name="book" type="bookType"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="bookType"> <xsd:sequence> <xsd:element name="title" type="xsd:string"/> <xsd:element name="author" type="authorName"/> <xsd:element name="price" type="xsd:decimal"/> </xsd:sequence> <xsd:attribute name="genre" type="xsd:string"/> </xsd:complexType> <xsd:complexType name="authorName"> <xsd:sequence> <xsd:element name="first-name" type="xsd:string"/> <xsd:element name="last-name" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:schema>

Tengo un archivo XML con una ubicación de esquema específica como esta:

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

Quiero validar en C #. Visual Studio, cuando abro el archivo, lo valida contra el esquema y enumera los errores perfectamente. De alguna manera, sin embargo, parece que no puedo validarlo automáticamente en C # sin especificar el esquema para validarlo así:

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

¿No debería ser capaz de validar con el esquema especificado en el archivo XML automáticamente? Qué me estoy perdiendo ?


Hice este tipo de validación automática en VB y así es como lo hice (convertida a C #):

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

Luego me suscribí a la settings.ValidationEventHandler Evento settings.ValidationEventHandler mientras leía el archivo.


Necesita crear una instancia de XmlReaderSettings y pasarla a su XmlReader cuando la cree. Luego puede suscribirse al ValidationEventHandler en la configuración para recibir los errores de validación. Tu código terminará luciendo así:

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


Personalmente, estoy a favor de la validación sin una devolución de llamada:

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

(ver la publicación de Timiz0r en Validación de esquema XML síncrono? .NET 3.5 )


Una forma más simple, si usa .NET 3.5, es usar la validación de XDocument y XmlSchemaSet .

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

Consulte la documentación de MSDN para obtener más ayuda.