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
- Create the
XmlSchemaValidator
class.
- Create the XML Schema.
- 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.
using System;
using System.Xml;
using System.Xml.Schema;
using System.IO;
namespace YourNameSpace.GoesHere
{
public class XmlSchemaValidator
{
private bool isValidXml = true;
private string validationError = "";
public XmlSchemaValidator()
{
}
public String ValidationError
{
get
{
return "<VALIDATIONERROR>" + this.validationError
+ "</VALIDATIONERROR>";
}
set
{
this.validationError = value;
}
}
public bool IsValidXml
{
get
{
return this.isValidXml;
}
}
private void ValidationCallBack(object sender,
ValidationEventArgs args)
{
isValidXml = false;
this.ValidationError = args.Message;
}
public bool ValidXmlDoc(string xml,
string schemaNamespace, string schemaUri)
{
try
{
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;
}
}
public bool ValidXmlDoc(XmlDocument xml,
string schemaNamespace, string schemaUri)
{
try
{
if(xml == null)
{
return false;
}
StringWriter sw = new StringWriter();
XmlTextWriter xw = new XmlTextWriter(sw);
xml.WriteTo(xw);
string strXml = sw.ToString();
StringReader srXml = new StringReader(strXml);
return ValidXmlDoc(srXml, schemaNamespace, schemaUri);
}
catch(Exception ex)
{
this.ValidationError = ex.Message;
return false;
}
}
public bool ValidXmlDoc(StringReader xml,
string schemaNamespace, string schemaUri)
{
if(xml == null || schemaNamespace == null || schemaUri == null)
{
return false;
}
isValidXml = true;
XmlValidatingReader vr;
XmlTextReader tr;
XmlSchemaCollection schemaCol = new XmlSchemaCollection();
schemaCol.Add(schemaNamespace, schemaUri);
try
{
tr = new XmlTextReader(xml);
vr = new XmlValidatingReader(tr);
vr.ValidationType = ValidationType.Auto;
if(schemaCol != null)
{
vr.Schemas.Add(schemaCol);
}
vr.ValidationEventHandler +=
new ValidationEventHandler(ValidationCallBack);
while(vr.Read())
{
}
vr.Close();
return isValidXml;
}
catch(Exception ex)
{
this.ValidationError = ex.Message;
return false;
}
finally
{
vr = null;
tr = null;
}
}
}
}
XmlSchema Example
The following code is an example Schema file used to validate the example 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:
<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.
[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;
}