<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- Define the complex type product. -->
<xsd:complexType name="product">
<xsd:sequence>
<xsd:element name="productName" type="xsd:string"/>
<xsd:element name="productPrice" type="xsd:decimal"/>
<xsd:element name="inStock" type="xsd:boolean"/>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:integer"/>
</xsd:complexType>
<!-- This is the structure the document must match.
It begins with a productCatalog element that nests other elements. -->
<xsd:element name="productCatalog">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="catalogName" type="xsd:string"/>
<xsd:element name="expiryDate" type="xsd:date"/>
<xsd:element name="products">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="product" type="product"
maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<?xml version="1.0" ?>
<productCatalog>
<catalogName>Acme Fall 2003 Catalog</catalogName>
<expiryDate>Jan 1, 2004</expiryDate>
<products>
<product id="1001">
<productName>Magic Ring</productName>
<productPrice>$342.10</productPrice>
<inStock>true</inStock>
</product>
<product id="1002">
<productName>Flying Carpet</productName>
<productPrice>982.99</productPrice>
<inStock>Yes</inStock>
</product>
</products>
</productCatalog>
The next example shows a utility class that displays all errors in an XML document when the
ValidateXml method is called. Errors are displayed in a console window, and a final Boolean
variable is returned to indicate the success or failure of the entire validation operation.
using System;
using System.Xml;
using System.Xml.Schema;
public class ConsoleValidator {
// Set to true if at least one error exists.
private bool failed;
public bool Failed {
get {return failed;}
}
public bool ValidateXml(string xmlFilename, string schemaFilename) {
// Create the validator.
XmlTextReader r = new XmlTextReader(xmlFilename);
XmlValidatingReader validator = new XmlValidatingReader(r);
validator.ValidationType = ValidationType.Schema;
// Load the schema file into the validator.
XmlSchemaCollection schemas = new XmlSchemaCollection();
schemas.Add(null, schemaFilename);
validator.Schemas.Add(schemas);
// Set the validation event handler.
validator.ValidationEventHandler +=
new ValidationEventHandler(ValidationEventHandler);
failed = false;
try {
// Read all XML data.
while (validator.Read())
{}
}catch (XmlException err) {
// This happens if the XML document includes illegal characters
// or tags that aren't properly nested or closed.
Console.WriteLine("A critical XML error has occurred.");
Console.WriteLine(err.Message);
failed = true;
}finally {
validator.Close();
}
return !failed;
}
private void ValidationEventHandler(object sender,
ValidationEventArgs args) {
failed = true;
// Display the validation error.
Console.WriteLine("Validation error: " + args.Message);
Console.WriteLine();
}
}
Here's how you would use the class to validate the product catalog:
using System;
public class ValidateXml {
private static void Main() {
ConsoleValidator consoleValidator = new ConsoleValidator();
Console.WriteLine("Validating ProductCatalog.xml.");
bool success = consoleValidator.ValidateXml("ProductCatalog.xml",
"ProductCatalog.xsd");
if (!success) {
Console.WriteLine("Validation failed.");
}else {
Console.WriteLine("Validation succeeded.");
}
Console.ReadLine();
}
}
the result:
Validating ProductCatalog_Invalid.xml.
Validation error: The 'expiryDate' element has an invalid value according to
its data type. [path information truncated]
Validation error: The 'productPrice' element has an invalid value according to
its data type. [path information truncated]
Validation error: The 'inStock' element has an invalid value according to its
data type. [path information truncated]
Validation failed.
Finally, if you want to validate an XML document and then process it, you can use
XmlValidatingReader to scan a document as it's read into an in-memory XmlDocument.
Here's how it works:
XmlDocument doc = new XmlDocument();
XmlTextReader r = new XmlTextReader("ProductCatalog.xml");
XmlValidatingReader validator = new XmlValidatingReader(r);
// Load the schema into the validator.
validator.ValidationType = ValidationType.Schema;
XmlSchemaCollection schemas = new XmlSchemaCollection();
schemas.Add(null, "ProductCatalog.xsd");
validator.Schemas.Add(schemas);
// Load the document and validate it at the same time.
// Don't handle the ValidationEventHandler event. Instead, allow any errors
/// to be thrown as an XmlSchemaException.
try {
doc.Load(validator);
// (Validation succeeded if you reach here.)
}catch (XmlSchemaException err) {
// (Validation failed if you reach here.)
}