XmlValidatingReader の検証イベント ハンドラー コールバック

ValidationEventHandler イベントは、ドキュメント型定義 (DTD) スキーマによる検証エラー、XDR (XML-Data Reduced) スキーマによる検証エラー、および XML スキーマ定義言語 (XSD) スキーマによる検証エラーに関する情報を受信するイベント ハンドラーの設定に使用します。

検証エラーと警告は、ValidationEventHandler コールバックを通じて報告されます。ValidationEventHandler が指定されていない状態でパーサー エラーが発生した場合、そのエラーは XmlException の発生によって報告されます。検証エラーが発生した場合は、XmlSchemaException がスローされます。例外がスローされた場合、XmlValidatingReader を再起動することはできません。

注意

.NET Framework 2.0 では、XmlValidatingReader クラスが廃止されています。XmlReaderSettings クラスと Create メソッドを使用して、検証用の XmlReader インスタンスを作成できます。詳細については、「XmlReader による XML データの検証」を参照してください。

ValidationEventHandler の使用

ValidationType プロパティが ValidationType.DTD、ValidationType.Schema、ValidationType.XDR、または ValidationType.Auto に設定されている場合にのみ ValidationEventHandler を使用する検証イベントが発生します。ValidationType プロパティは既定で ValidationType.Auto に設定されます。

XML スキーマおよび XDR スキーマが XmlSchemaCollection に追加されると、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 クラスの使用