XML

Validating XML against XSD schemas in C#

I’m currently working on an XML File Explorer application, which I intend on highlighting XML files which do not conform to an XSD schema, as part of this I have created a class for containing the details of performing XSD validation against an XML document, which I thought I would share with you (although the XML File Explorer will be open source).

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Schema;

namespace KetoLibrary.Xml
{
    public class XsdValidator
    {
        public List<XmlSchema> Schemas { get; set; }
        public List<String> Errors { get; set; }
        public List<String> Warnings { get; set; }

        public XsdValidator()
        {
            Schemas = new List<XmlSchema>();
        }

        /// <summary>
        /// Add a schema to be used during the validation of the XML document
        /// </summary>
        /// <param name="schemaFileLocation">The file path for the XSD schema file to be added for validation</param>
        /// <returns>True if the schema file was successfully loaded, else false (if false, view Errors/Warnings for reason why)</returns>
        public bool AddSchema(string schemaFileLocation)
        {
            if (String.IsNullOrEmpty(schemaFileLocation)) return false;
            if (!File.Exists(schemaFileLocation)) return false;

            // Reset the Error/Warning collections
            Errors = new List<string>();
            Warnings = new List<string>();

            XmlSchema schema;

            using (var fs = File.OpenRead(schemaFileLocation))
            {
                schema = XmlSchema.Read(fs, ValidationEventHandler);
            }

            var isValid = !Errors.Any() && !Warnings.Any();

            if (isValid)
            {
                Schemas.Add(schema);
            }

            return isValid;
        }

        /// <summary>
        /// Perform the XSD validation against the specified XML document
        /// </summary>
        /// <param name="xmlLocation">The full file path of the file to be validated</param>
        /// <returns>True if the XML file conforms to the schemas, else false</returns>
        public bool IsValid(string xmlLocation)
        {
            if (!File.Exists(xmlLocation))
            {
                throw new FileNotFoundException("The specified XML file does not exist", xmlLocation);
            }

            using (var xmlStream = File.OpenRead(xmlLocation))
            {
                return IsValid(xmlStream);
            }
        }

        /// <summary>
        /// Perform the XSD validation against the supplied XML stream
        /// </summary>
        /// <param name="xmlStream">The XML stream to be validated</param>
        /// <returns>True is the XML stream conforms to the schemas, else false</returns>
        private bool IsValid(Stream xmlStream)
        {
            // Reset the Error/Warning collections
            Errors = new List<string>();
            Warnings = new List<string>();

            var settings = new XmlReaderSettings
            {
                ValidationType = ValidationType.Schema
            };
            settings.ValidationEventHandler += ValidationEventHandler;

            foreach (var xmlSchema in Schemas)
            {
                settings.Schemas.Add(xmlSchema);
            }

            var xmlFile = XmlReader.Create(xmlStream, settings);

            try
            {
                while (xmlFile.Read()) { }
            }
            catch (XmlException xex)
            {
                Errors.Add(xex.Message);
            }

            return !Errors.Any() && !Warnings.Any();
        }

        private void ValidationEventHandler(object sender, ValidationEventArgs e)
        {
            switch (e.Severity)
            {
                case XmlSeverityType.Error:
                    Errors.Add(e.Message);
                    break;
                case XmlSeverityType.Warning:
                    Warnings.Add(e.Message);
                    break;
            }
        }
    }
}

The code is pretty simple but I’m a fan of hiding away any complexities so that I don’t have to think about them when I’m working on a project. The usage for this class is pretty simple as well, requiring you pass in the XSD schemas and then call IsValid specifying the XML file to validate.

public void MultipleSchemas()
{
    var validator = new XsdValidator();
    validator.AddSchema(@"SchemaDoc1.xsd");
    validator.AddSchema(@"SchemaDoc2.xsd");
    var isValid = validator.IsValid(@"ValidXmlDoc1.xml");
}

Both the XsdValidator and the usage example are hosted on GitHub Gists so feel free to head over to here and do what you want.

7 thoughts on “Validating XML against XSD schemas in C#”

  1. For me, not working. I test with my XSD, and XML that not matches XSD and I get OK value, not KO.

    This code is working for me.

    using (var xtrReader = new XmlTextReader(strXsdLocation))
    {

    var xcSchemaCollection = new XmlSchemaCollection();
    xcSchemaCollection.Add(null/*add your namespace string*/, xtrReader);

    var vrValidator = new XmlValidatingReader(strXml, XmlNodeType.Document, null);
    vrValidator.Schemas.Add(xcSchemaCollection);

    // Add validation event handler
    vrValidator.ValidationType = ValidationType.Schema;
    vrValidator.ValidationEventHandler += new ValidationEventHandler(ValidationHandler);

    //Actual validation, read conforming the schema.
    while (vrValidator.Read()) ;

    vrValidator.Close();//Cleanup

    //Exception if error.
    if (nErrors > 0) { throw new Exception(strErrorMsg); }
    else { bStatus = true; }//Success
    }

  2. Using your code, only I added this line

    settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;

    and ALL is OK. Detect warnings and I get error in validation XML against XSD.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.