Click here to Skip to main content
15,861,172 members
Articles / Programming Languages / XML

C# - XML Schema Validator

Rate me:
Please Sign up or sign in to vote.
4.90/5 (31 votes)
12 Nov 2004CPOL1 min read 322.9K   4K   87   20
This article demonstrates the use of an XML Schema validation class.

Introduction

Have you ever worked on a project utilizing Web Services, XML, and Schemas? Then you probably have needed to ensure the validity of the XML being passed to the Web Service against the Schema. This article shows how to use .NET's XmlValidatingReader to validate XML with a schema.

Using the code

  1. Create the XmlSchemaValidator class.
  2. Create the XML Schema.
  3. Create a WebService and add the ValidateXML method.

Note: All of the code is available via the downloadable zip file.

XmlSchemaValidator Class

The XmlSchemaValidator class contains an overloaded publicly available method ValidXmlDoc. This method allows the caller to pass in either a string of XML, an XmlDocument, or a StringReader of xml. The other parameters are the namespace and URI of the schema used to validate the XML. The method returns a boolean value, true if the XML is valid, false if the XML is invalid. There is also a publicly available string "ValidationError" that contains the validation error.

C#
using System;
using System.Xml;
using System.Xml.Schema;
using System.IO;


namespace YourNameSpace.GoesHere
{
    /// <SUMMARY>
    /// This class validates an xml string or xml document against an xml
        /// schema.
    /// It has public methods that return a boolean value depending on 
        /// the validation
    /// of the xml.
    /// </SUMMARY>
    public class XmlSchemaValidator
    {
        private bool isValidXml = true;
        private string validationError = "";

        /// <SUMMARY>
        /// Empty Constructor.
        /// </SUMMARY>
        public XmlSchemaValidator()
        {
            
        }

        /// <SUMMARY>
        /// Public get/set access to the validation error.
        /// </SUMMARY>
        public String ValidationError
        {
            get
            {
                return "<VALIDATIONERROR>" + this.validationError 
                       + "</VALIDATIONERROR>";
            }
            set
            {
                this.validationError = value;
            }
        }

        /// <SUMMARY>
        /// Public get access to the isValidXml attribute.
        /// </SUMMARY>
        public bool IsValidXml
        {
            get
            {
                return this.isValidXml;
            }
        }

        /// <SUMMARY>
        /// This method is invoked when the XML does not match
        /// the XML Schema.
        /// </SUMMARY>
        /// <PARAM name="sender"></PARAM>
        /// <PARAM name="args"></PARAM>
        private void ValidationCallBack(object sender, 
                                   ValidationEventArgs args)
        {
            // The xml does not match the schema.
            isValidXml = false;
            this.ValidationError = args.Message;
        }  


        /// <SUMMARY>
        /// This method validates an xml string against an xml schema.
        /// </SUMMARY>
        /// <PARAM name="xml">XML string</PARAM>
        /// <PARAM name="schemaNamespace">XML Schema Namespace</PARAM>
        /// <PARAM name="schemaUri">XML Schema Uri</PARAM>
        /// <RETURNS>bool</RETURNS>
        public bool ValidXmlDoc(string xml, 
               string schemaNamespace, string schemaUri)
        {
          try
          {
               // Is the xml string valid?
               if(xml == null || xml.Length <  1)
               {
                   return false;
               }

               StringReader srXml = new StringReader(xml);
               return ValidXmlDoc(srXml, schemaNamespace, schemaUri);
          }
          catch(Exception ex)
          {
              this.ValidationError = ex.Message;
              return false;
          }
        }

        /// <SUMMARY>
        /// This method validates an xml document against an xml 
                /// schema.
        public bool ValidXmlDoc(XmlDocument xml, 
               string schemaNamespace, string schemaUri)
        {
            try
            {
                // Is the xml object valid?
                if(xml == null)
                {
                    return false;
                }

                // Create a new string writer.
                StringWriter sw = new StringWriter();
                // Set the string writer as the text writer 
                                // to write to.
                XmlTextWriter xw = new XmlTextWriter(sw);
                // Write to the text writer.
                xml.WriteTo(xw);
                // Get 
                string strXml = sw.ToString();

                StringReader srXml = new StringReader(strXml);

                return ValidXmlDoc(srXml, schemaNamespace, schemaUri);
            }
            catch(Exception ex)
            {
                this.ValidationError = ex.Message;
                return false;
            }
        }

        /// <SUMMARY>
        /// This method validates an xml string against an xml schema.
        /// </SUMMARY>
        /// <PARAM name="xml">StringReader containing xml</PARAM>
        /// <PARAM name="schemaNamespace">XML Schema Namespace</PARAM>
        /// <PARAM name="schemaUri">XML Schema Uri</PARAM>
        /// <RETURNS>bool</RETURNS>
        public bool ValidXmlDoc(StringReader xml, 
               string schemaNamespace, string schemaUri)
        {
            // Continue?
            if(xml == null || schemaNamespace == null || schemaUri == null)
            {
                return false;
            }

            isValidXml = true;
            XmlValidatingReader vr;
            XmlTextReader tr;
            XmlSchemaCollection schemaCol = new XmlSchemaCollection();
            schemaCol.Add(schemaNamespace, schemaUri);

            try 
            { 
                // Read the xml.
                tr = new XmlTextReader(xml);
                // Create the validator.
                vr = new XmlValidatingReader(tr);
                // Set the validation tyep.
                vr.ValidationType = ValidationType.Auto;
                // Add the schema.
                if(schemaCol != null)
                {
                    vr.Schemas.Add(schemaCol);
                }
                // Set the validation event handler.
                vr.ValidationEventHandler += 
                   new ValidationEventHandler(ValidationCallBack);
                // Read the xml schema.
                while(vr.Read()) 
                { 
                } 

                vr.Close(); 

                return isValidXml;
            } 
            catch(Exception ex) 
            { 
                this.ValidationError = ex.Message;
                return false; 
            } 
            finally
            {
                // Clean up...
                vr = null;
                tr = null;
            }
        }
    }
}

XmlSchema Example

The following code is an example Schema file used to validate the example XML:

XML
<xs:schema id="XSDSchemaTest"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  elementFormDefault="qualified" 
  attributeFormDefault="unqualified"
>

 <xs:simpleType name="FamilyMemberType">
  <xs:restriction base="xs:string">
   <xs:enumeration value="384" />
   <xs:enumeration value="385" />
   <xs:enumeration value="386" />
   <xs:enumeration value="" />
  </xs:restriction>        
 </xs:simpleType>

   <xs:element name="Answer">
     <xs:complexType>
    <xs:sequence>
      <xs:element name="ShortDesc" type="FamilyMemberType" />
      <xs:element name="AnswerValue" type="xs:int" />
     </xs:sequence>
      </xs:complexType>
     </xs:element>
</xs:schema>

XML Example

Example XML validated against the schema:

XML
<Answer>
    <ShortDesc>385</ShortDesc> 
    <AnswerValue>1</AnswerValue> 
</Answer>

WebService Example

The WebService has a publicly available method that validates the XML. This method provides an example to one of the many ways the validator object may be used. Remember, there are three overloads to the ValidXmlDoc method.

C#
[WebMethod]
public string ValidateXml(string xml)
{
    XmlSchemaValidator validator = new XmlSchemaValidator();

    string retVal = "<VALIDXML>" + 
           validator.ValidXmlDoc(xml, "", 
           Server.MapPath("XSDSchemaTest.xsd")).ToString() + 
           "</VALIDXML>";

    if(!validator.IsValidXml)
    {
        retVal = retVal + validator.ValidationError;
    }

    return retVal;
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionCould not create type 'ProtocolManager.WebApp.PMWebService' Pin
Member 121251328-Nov-15 22:22
Member 121251328-Nov-15 22:22 
GeneralGreat work and thank you! Pin
artyr12331-Mar-15 8:44
artyr12331-Mar-15 8:44 
GeneralMy vote of 2 Pin
zg913fz@hotmail.com28-Jul-14 21:15
zg913fz@hotmail.com28-Jul-14 21:15 
Questionclass throws exception Pin
saurabh19880111-Feb-13 0:05
saurabh19880111-Feb-13 0:05 
GeneralMy vote of 5 Pin
VMAtm18-Sep-12 0:09
VMAtm18-Sep-12 0:09 
QuestionWhat can I do? Pin
jinda_tra@hotmail.com9-Nov-06 17:33
jinda_tra@hotmail.com9-Nov-06 17:33 
Generalexception on using xmlschemavalidator class [modified] Pin
ninja260523-Aug-06 1:36
ninja260523-Aug-06 1:36 
GeneralRe: exception on using xmlschemavalidator class Pin
Murpheux Melony17-Apr-07 12:53
Murpheux Melony17-Apr-07 12:53 
QuestionValidation failed unexpectantly??? Pin
Richard Beacroft5-Jan-06 1:20
Richard Beacroft5-Jan-06 1:20 
Unfortunately, I always receive an error:

<string xmlns="http://www.usf.edu/dtcc/">
<validxml>False
<validationerror>The 'http://tempuri.org/xmlvalid_test.xsd:AnswerValue' element is not declared. An error occurred at , (1, 81).


XSD:
<?xml version="1.0" ?><br />
<xs:schema id="XSDSchemaTest" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"<br />
	attributeFormDefault="unqualified"><br />
	<xs:simpleType name="FamilyMemberType"><br />
		<xs:restriction base="xs:string"><br />
			<xs:enumeration value="384" /><br />
			<xs:enumeration value="385" /><br />
			<xs:enumeration value="386" /><br />
			<xs:enumeration value="" /><br />
		</xs:restriction><br />
	</xs:simpleType><br />
	<xs:element name="Answer"><br />
		<xs:complexType><br />
			<xs:sequence><br />
				<xs:element name="ShortDesc" type="FamilyMemberType" /><br />
				<xs:element name="AnswerValue" type="xs:integer" /><br />
			</xs:sequence><br />
		</xs:complexType><br />
	</xs:element><br />
</xs:schema>


XML:
<Answer xmlns="http://tempuri.org/xmlvalid_test.xsd"><br />
    <ShortDesc>385</ShortDesc><br />
    <AnswerValue>1</AnswerValue><br />
</Answer>


Any ideas where I'm going wrong???

Regards,

Rik
Questionread xml schema Pin
Anonymous27-Sep-05 2:55
Anonymous27-Sep-05 2:55 
Generalmultiple namespace Pin
Anonymous8-Jun-05 22:15
Anonymous8-Jun-05 22:15 
GeneralHelp! Pin
Anonymous7-Jun-05 23:31
Anonymous7-Jun-05 23:31 
GeneralRe: Help! Pin
Kenneth Young15-Jun-05 5:05
Kenneth Young15-Jun-05 5:05 
Generalusing schemaLocation attribute Pin
BigDave6423-Mar-05 14:43
BigDave6423-Mar-05 14:43 
GeneralRe: using schemaLocation attribute Pin
Kenneth Young24-Mar-05 3:48
Kenneth Young24-Mar-05 3:48 
GeneralRe: using schemaLocation attribute Pin
BigDave6431-Mar-05 9:23
BigDave6431-Mar-05 9:23 
GeneralRe: using schemaLocation attribute Pin
Kenneth Young1-Apr-05 3:39
Kenneth Young1-Apr-05 3:39 
GeneralRe: using schemaLocation attribute Pin
SixPeak9-Oct-08 15:56
SixPeak9-Oct-08 15:56 
GeneralThis method never parses the xml document Pin
lemuel5516-Jan-05 3:13
lemuel5516-Jan-05 3:13 
GeneralRe: This method never parses the xml document Pin
Kenneth Young18-Jan-05 6:06
Kenneth Young18-Jan-05 6:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.