You are accepting an XML document created by another source and you want to verify that it conforms to a specific schema. This schema may be in the form of an XSD or XDR schema; alternatively, you want the flexibility to use a DTD to validate the XML.
Use the
XmlValidatingReader
to validate XML documents
against any descriptor document, such as an XSD (XML Schema), a DTD
(Document Type Definition), or an XDR (Xml-Data Reduced):
public static void ValidateXML( ) { // create XSD schema collection with book.xsd XmlSchemaCollection schemaCollection = new XmlSchemaCollection( ); // wire up handler to get any validation errors schemaCollection.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack); // add book.xsd schemaCollection.Add(null, @"....Book.xsd"); // make sure we added if(schemaCollection.Count > 0) { // open the book.xml file XmlTextReader reader = new XmlTextReader(@"....Book.xml"); // set up the validating reader XmlValidatingReader validReader = new XmlValidatingReader(reader); // set the validation type and add the schema collection validReader.ValidationType = ValidationType.Schema; validReader.Schemas.Add(schemaCollection); // wire up for any validation errors from the validating // reader validReader.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack); // read all nodes and print out while (validReader.Read( )) { if(validReader.NodeType == XmlNodeType.Element) { Console.Write("<{0}", validReader.Name); while(validReader.MoveToNextAttribute( )) { Console.Write(" {0}='{1}'",validReader.Name, validReader.Value); } Console.Write(">"); } else if(validReader.NodeType == XmlNodeType.Text) { Console.Write(validReader.Value); } else if(validReader.NodeType == XmlNodeType.EndElement) { Console.WriteLine("</{0}>",validReader.Name); } } } } private static void ValidationCallBack(object sender, ValidationEventArgs e) { Console.WriteLine("Validation Error: {0}", e.Message); }
The Solution illustrates how to use the
XmlValidatingReader
to validate the
book.xml
document against a
book.xsd
XML Schema definition file. DTDs were
the original way to specify the structure of an XML document, but it
has become more common to use XML Schema since it reached W3C
Recommendation status in May 2001. XDR was an early form of the final
XML Schema syntax provided by Microsoft, and, while it might be
encountered in existing systems, it should not be used for new
development.
The first thing to do is create an
XmlSchemaCollection
to hold our XSD
(book.xsd
):
// create XSD schema collection with book.xsd XmlSchemaCollection schemaCollection = new XmlSchemaCollection( ); // wire up handler to get any validation errors schemaCollection.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack); // add book.xsd schemaCollection.Add(null, @"....Book.xsd");
This code also hooks up the schema collection event handler for
validation errors to the ValidationCallback
function that writes out the validation error message:
private static void ValidationCallBack(object sender, ValidationEventArgs e) { Console.WriteLine("Validation Error: {0}", e.Message); }
Once we have the schema collection, we create an
XmlTextReader
to load the
book.xml
file and then use the
XmlTextReader
to create our
XmlValidatingReader
:
// open the book.xml file XmlTextReader reader = new XmlTextReader(@"....Book.xml"); // set up the validating reader XmlValidatingReader validReader = new XmlValidatingReader(reader);
The XmlValidatingReader
error handler is also
wired up to the ValidationCallback
function; we
then proceed to roll over the XML document and write out the elements
and attributes. Setting the
XmlValidationReader.ValidationType
to
ValidationType.Schema
tells the
XmlValidatingReader
to perform XML Schema
validation. To perform DTD validation, use a DTD and
ValidationType.DTD
, and to perform XDR validation,
use an XDR schema and ValidationType.XDR
:
// set the validation type and add the schema collection validReader.ValidationType = ValidationType.Schema; validReader.Schemas.Add(schemaCollection); // wire up for any validation errors from the validating // reader validReader.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack); // read all nodes and print out while (validReader.Read( )) { if(validReader.NodeType == XmlNodeType.Element) { Console.Write("<{0}", validReader.Name); while(validReader.MoveToNextAttribute( )) { Console.Write(" {0}='{1}'",validReader.Name, validReader.Value); } Console.Write(">"); } else if(validReader.NodeType == XmlNodeType.Text) { Console.Write(validReader.Value); } else if(validReader.NodeType == XmlNodeType.EndElement) { Console.WriteLine("</{0}>",validReader.Name); } }
The book.xml
file contains the following:
<?xml version="1.0" encoding="utf-8"?> <Book xmlns="http://tempuri.org/Book.xsd" name="C# Cookbook"> <Chapter>File System IO</Chapter> <Chapter>Security</Chapter> <Chapter>Data Structures and Algorithms</Chapter> <Chapter>Reflection</Chapter> <Chapter>Threading</Chapter> <Chapter>Numbers</Chapter> <Chapter>Strings</Chapter> <Chapter>Classes And Structures</Chapter> <Chapter>Collections</Chapter> <Chapter>XML</Chapter> <Chapter>Delegates And Events</Chapter> <Chapter>Diagnostics</Chapter> <Chapter>Enums</Chapter> <Chapter>Unsafe Code</Chapter> <Chapter>Regular Expressions</Chapter> </Book>
The book.xsd
file contains the following:
<?xml version="1.0" ?> <xs:schema id="NewDataSet" targetNamespace="http://tempuri.org/Book.xsd" xmlns: mstns="http://tempuri.org/Book.xsd" xmlns="http://tempuri.org/Book.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified"> <xs:element name="Book"> <xs:complexType> <xs:sequence> <xs:element name="Chapter" nillable="true" minOccurs="0" maxOccurs="unbounded"> <xs:complexType> <xs:simpleContent msdata:ColumnName="Chapter_Text" msdata:Ordinal="0"> <xs:extension base="xs:string"> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="name" form="unqualified" type="xs:string"/> </xs:complexType> </xs:element> </xs:schema>