Recipe 17.4 Validating XML

Problem

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.

Solution

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); } 

Discussion

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> 

See Also

See the "XmlValidatingReader Class," "XmlSchemaCollection Class," "ValidationEventHandler Class," "ValidationType Enumeration," and "Introduction to XML Schemas" topics in the MSDN documentation.



C# Cookbook
C# 3.0 Cookbook
ISBN: 059651610X
EAN: 2147483647
Year: 2003
Pages: 315

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net