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.

Validating XML against XSD schemas in C#
Tagged on:     

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

  • February 17, 2014 at 9:30 am
    Permalink

    good it helps me a lot

    Reply
  • January 26, 2015 at 9:03 pm
    Permalink

    Thank You For Every Thinks

    Reply
  • June 22, 2015 at 1:09 pm
    Permalink

    Thank you Sam for your blog and this code

    Reply
  • March 6, 2017 at 3:25 pm
    Permalink

    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
    }

    Reply
  • March 7, 2017 at 3:46 pm
    Permalink

    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.

    Reply

Leave a Reply