Share via


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

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

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

ValidationEventHandler の使用

ValidationEventHandler に関連する検証イベントは、ReadReadInnerXmlReadOuterXml、または Skip の呼び出し時に XmlValidatingReaderValidationType プロパティが ValidationType.DTDValidationType.SchemaValidationType.XDR、または ValidationType.Auto に設定されている場合にだけ発生します。既定では、ValidationType プロパティは ValidationType.Auto に設定されます。

XmlSchemaCollection クラスは、XML スキーマおよび XDR スキーマが自ら追加された場合、ValidationEventHandler イベントを使用して、これらのスキーマの検証エラーを処理します。

検証イベント ハンドラを指定した ValidationCallback メソッドを次のサンプル コードに示します。

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

ValidationEventArgs クラスには、テキスト メッセージ用のプロパティ、Error または Warning を示す XmlSeverityType 列挙型、および特定の検証エラーに関連付けられている XmlSchemaException 情報を保持している例外があります。

イベント ハンドラが提供されていない場合は、XmlSeverityType = Error に該当する最初の検証エラーに対して例外がスローされます。このエラーが発生すると、XmlValidatingReader を再起動できなくなります。XmlSeverityType = Warning の該当する検証エラーに関して、例外が発生することはありません。スキーマまたは DTD に基づいた検証の実行中にエラーが発生した場合は、XmlSchemaException がスローされます。

コンテンツ モデルの不一致が原因で、ある要素や属性が ValidationCallback メソッドをとおして検証エラーを報告した場合、コンテンツ モデルの残りの部分では、その要素や属性の検証が行われません。ただし、その要素や属性の子要素は検証されます。XmlValidatingReader は、ある要素のエラーを認識した時点で、その要素の検証を停止します。

検証結果の確認

XML インスタンス ドキュメントの検証ステータスを確認するには、ValidationEventHandler イベントおよび XmlSeverityType 列挙型を使用します。致命的な検証エラーが発生した場合、Severity プロパティの値は XmlSeverityType.Error になり、致命的なエラーが発生したことを知らせます。要素や属性の検証に使用できるスキーマ情報や DTD 情報がないために返されたエラーなど、致命的ではない検証エラーが発生した場合、Severity プロパティの値は XmlSeverityType.Warning になります。警告は、ValidationType.None 以外のすべての ValidationType 値に対して発生する可能性があります。

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

        }
    }
}

検証対象の入力ファイル 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
[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);
}

参照

XmlValidatingReader を使用した XML の検証 | スキーマとの XML の検証