Validate an XML Document Against a Schema(XML 三)
Solution
Use the System.Xml.XmlValidatingReader class. Create an instance, load a schema into the XmlValidatingReader.Schemas collection, and then move through the document one node at a time by calling XmlValidatingReader.Read, catching any validation exceptions. To find all the errors in a document without catching exceptions, handle the ValidationEventHandler event.
Here's the complete schema for the product catalog XML:
<?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.) }
posted on 2005-11-23 18:26 夢在天涯 閱讀(965) 評論(0) 編輯 收藏 引用 所屬分類: C#/.NET