XmlValidatingReader Validation Event Handler Callback
The ValidationEventHandler event is used to set an event handler for receiving information about document type definition (DTD), XML-Data Reduced (XDR), and XML Schema definition language (XSD) schema validation errors.
Validation errors and warnings are reported through the ValidationEventHandler callback. If no ValidationEventHandler is supplied and a parse error occurs, the error is reported by raising an XmlException. If a validation error occurs, an XmlSchemaException is thrown. If an exception is thrown, the XmlValidatingReader cannot be restarted.
Using the ValidationEventHandler
Validation events with ValidationEventHandler happen only if the ValidationType property of XmlValidatingReader is set to ValidationType.DTD, ValidationType.Schema, ValidationType.XDR, or ValidationType.Auto during a Read, ReadInnerXml, ReadOuterXml, or Skip call. By default the ValidationType property is set to ValidationType.Auto.
The XmlSchemaCollection class uses the ValidationEventHandler event to handle validation errors in XML Schema and XDR schema when those schemas are added in the XmlSchemaCollection.
The following code example demonstrates the ValidationCallback method when a validation event handler is supplied.
Sub ValidationCallback(sender As Object, args As ValidationEventArgs)
End Sub
[C#]
void ValidationCallback(object sender, ValidationEventArgs e)
{
}
The ValidationEventArgs class has properties for a text message, an XmlSeverityType enumeration indicating Error or Warning, and an exception that contains XmlSchemaException information associated with the particular validation error.
If no event handler is provided, an exception is thrown for the first validation error with XmlSeverityType = Error
. The XmlValidatingReader cannot be restarted after this error. Exceptions are not raised for validation errors with XmlSeverityType = Warning
. An XmlSchemaException is thrown if the validation error occurred while validating against a schema or DTD.
If a given element or attribute reports a validity error through the ValidationCallback method because the content model does not match, the rest of the content model for that element is not validated. (The child elements of the given element or attribute, however, are validated.) After the XmlValidatingReader identifies an error for a given element, it stops validating that element.
Checking the Validation Result
The ValidationEventHandler event and XmlSeverityType enumeration can be used to verify the validation status of an XML instance document. For fatal validation errors, the Severity property has the value of XmlSeverityType.Error, indicating that a fatal error has occurred. For all nonfatal validation errors (for example, those returned because there is no schema or DTD information available to validate the elements and attributes), the Severity property has the value XmlSeverityType.Warning. Warnings can occur for all ValidationType values except ValidationType.None.
The following code example shows the use of the ValidationEventHandler event to validate an XML instance document against an XML Schema in an XmlSchemaCollection.
Private Shared reader As XmlValidatingReader = Nothing
Private Shared treader As XmlTextReader = Nothing
Private Shared filename As [String] = String.Empty
Public Overloads Shared Sub Main()
Dim xsc As New XmlSchemaCollection()
Try
xsc.Add(Nothing, New XmlTextReader("MySchema.xsd"))
treader = New XmlTextReader("Myfilename.xml")
reader = New XmlValidatingReader(treader)
reader.Schemas.Add(xsc)
reader.ValidationType = ValidationType.Schema
AddHandler reader.ValidationEventHandler, AddressOf sample.ValidationCallback
While reader.Read()
End While
Catch e As Exception
If Not (reader Is Nothing) Then
reader.Close()
End If
Console.WriteLine(e.ToString())
End Try
End Sub
' Main
Shared Sub ValidationCallback(sender As Object, args As ValidationEventArgs)
If args.Severity = XmlSeverityType.Warning Then
Console.WriteLine("No schema found to enforce validation.")
Console.WriteLine((filename + "(" + treader.LineNumber + "," + treader.LinePosition + ")" + args.Message))
End If
' ValidationCallback
End Sub
[C#]
using System;
using System.IO;
using System.Xml;
using System.Xml.Schema;
public class Sample
{
static String filename = "BooksSchema.xml";
static XmlTextReader treader = null;
public static void Main()
{
XmlValidatingReader reader = null;
XmlSchemaCollection xsc = new XmlSchemaCollection();
ValidationEventHandler eventHandler = new ValidationEventHandler(Sample.ValidationCallback);
try
{
xsc.Add(null, new XmlTextReader("Books.xsd"));
treader = new XmlTextReader(filename);
reader = new XmlValidatingReader(treader);
reader.Schemas.Add(xsc);
reader.ValidationType = ValidationType.Schema;
reader.ValidationEventHandler += eventHandler;
while (reader.Read())
{
}
Console.WriteLine("Validation successful.");
}
catch (Exception e)
{
if ( reader != null )
reader.Close();
Console.WriteLine(e.ToString());
}
}
public static void ValidationCallback(object sender, ValidationEventArgs args )
{
if (args.Severity == XmlSeverityType.Warning)
{
Console.WriteLine("No schema found to enforce validation.");
Console.WriteLine(filename + "(" + treader.LineNumber + "," + treader.LinePosition + ")" + args.Message);
}
}
}
The following outlines the contents of the input file, BooksSchema.xml, to be validated.
<?xml version='1.0'?>
<bookstore xmlns="urn:bookstore-schema">
<book genre="autobiography">
<title>The Autobiography of Benjamin Franklin</title>
<author>
<first-name>Benjamin</first-name>
<last-name>Franklin</last-name>
</author>
<price>8.99</price>
</book>
<book genre="novel">
<title>The Confidence Man</title>
<author>
<first-name>Herman</first-name>
<last-name>Melville</last-name>
</author>
<price>11.99</price>
</book>
</bookstore>
The following outlines the contents of the input file, Books.xsd, to be validated against.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="urn:bookstore-schema"
elementFormDefault="qualified"
targetNamespace="urn:bookstore-schema">
<xs:element name="bookstore" type="bookstoreType"/>
<xs:complexType name="bookstoreType">
<xs:sequence maxOccurs="unbounded">
<xs:element name="book" type="bookType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="bookType">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="author" type="authorName"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
<xs:attribute name="genre" type="xs:string"/>
</xs:complexType>
<xs:complexType name="authorName">
<xs:sequence>
<xs:element name="first-name" type="xs:string"/>
<xs:element name="last-name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
The following code example shows the use of the ValidationEventHandler event. Any errors are written to the console.
' Set the validation event handler.
AddHandler reader.ValidationEventHandler, AddressOf ValidationCallBack
Private Sub ValidationCallBack(sender As Object, args As ValidationEventArgs)
Console.WriteLine("Validation CallBack: type: {0} message: {1}", args.Severity, args.Message)
' ValidationCallBack
End Sub
[C#]
// Set the validation event handler.
reader.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);
private void ValidationCallBack(object sender, ValidationEventArgs args )
{
Console.WriteLine("Validation CallBack: type: {0} message: {1}", args.Severity, args.Message);
}
See Also
Validation of XML with XmlValidatingReader | Validation of XML with Schemas