XmlValidatingReader 验证事件处理程序回调

ValidationEventHandler 事件用于设置一个事件处理程序以接收有关文档类型定义 (DTD)、XML 数据缩减 (XDR) 和 XML 架构定义语言 (XSD) 架构验证错误的信息。

通过 ValidationEventHandler 回调报告验证错误和警告。 如果不提供 ValidationEventHandler,当发生分析错误时,将通过引发 XmlException 报告错误。 如果发生验证错误,将引发 XmlSchemaException。 如果引发了异常,将无法重新启动 XmlValidatingReader

注意注意

XmlValidatingReader 类在 .NET Framework 2.0 版 中已过期。您可以使用 XmlReaderSettings 类和 Create 方法创建一个验证 XmlReader 实例。有关更多信息,请参见使用 XmlReader 验证 XML 数据

使用 ValidationEventHandler

只有在 ValidationType 属性设置为 ValidationType.DTD、ValidationType.Schema、ValidationType.XDR 或 ValidationType.Auto 时,才会发生 ValidationEventHandler 的验证事件。 默认情况下,ValidationType 属性设置为 ValidationType.Auto。

XmlSchemaCollection 类在将 XML 架构和 XDR 架构添加到 XmlSchemaCollection 中时,使用 ValidationEventHandler 事件处理这些架构中的验证错误。

下面的代码示例说明当提供验证事件处理程序时的 ValidationCallback 方法。

Sub ValidationCallback(sender As Object, args As ValidationEventArgs)
End Sub
void ValidationCallback(object sender, ValidationEventArgs e)
{
}

ValidationEventArgs 类具有一个文本消息、一个 XmlSeverityType 枚举(指示属于验证错误还是警告)和一个异常(包含与特定验证错误关联的 XmlSchemaException 信息)的属性。

如果不提供事件处理程序,则对于第一个 XmlSeverityType = Error 的验证错误引发异常。 发生此错误后将无法重新启动 XmlValidatingReader。 对于 XmlSeverityType = Warning 的验证错误不会引发异常。 当根据架构或 DTD 进行验证时,如果发生验证错误,将引发 XmlSchemaException

如果由于内容模型不匹配,给定的元素或属性通过 ValidationCallback 方法报告有效性错误,则不会对该元素的内容模型的其余部分进行验证。 (然而,将对给定元素或属性的子元素进行验证。)当 XmlValidatingReader 识别出给定元素的错误后,将停止验证该元素。

检查验证结果

ValidationEventHandler 事件和 XmlSeverityType 枚举可用于校验 XML 实例文档的验证状态。 对于致命的验证错误,ValidationEventArgs.Severity 属性的值为 XmlSeverityType.Error,指示发生致命错误。 对于所有非致命的验证错误(例如因为验证元素和属性时没有可用架构或 DTD 信息而返回的错误),Severity 属性的值为 XmlSeverityType.Warning。 所有 ValidationType 值(ValidationType.None 除外)都可能出现警告。

注意注意

不支持在 ValidationEventHandler 内调用任何更改读取器状态的方法。例如,在事件处理程序中显式或隐式对读取器调用 Read() 时,我们无法保证读取器的状态。

下面的代码示例说明如何使用 ValidationEventHandler 事件,根据 XmlSchemaCollection 中的 XML 架构对 XML 实例文档进行验证。

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

        }
    }
}

下面概括了要验证的输入文件 BooksSchema.xml 的内容。

<?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>

下面概括了作为验证依据的输入文件 Books.xsd 的内容。

<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>

下面的代码示例显示 ValidationEventHandler 事件的用法。 所有错误都被写到控制台。

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

请参见

概念

用 XmlReader 读取 XML

其他资源

使用 XmlReader 类