次の方法で共有


XPathNavigator を使用したスキーマ検証

XmlDocument クラスを使用して、XmlDocument オブジェクトに含まれる XML コンテンツを 2 つの方法で検証することができます。 最初の方法は、検証型 XmlReader オブジェクトを使用して XML コンテンツを検証する方法で、2 番目の方法は、Validate クラスの XmlDocument メソッドを使用する方法です。 XPathDocument クラスを使用して XML コンテンツの読み取り専用の検証を行うこともできます。

XML データの検証

XmlDocument クラスは、既定では DTD または XML スキーマ定義言語 (XSD) のスキーマ検証を使用した XML ドキュメントの検証は行いません。 XML ドキュメントが整形式であることを確認するだけです。

XML ドキュメントを検証する最初の方法は、検証型の XmlDocument オブジェクトを使用して、ドキュメントが XmlReader オブジェクトに読み込まれる際に検証する方法です。 2 番目の方法は、Validate クラスの XmlDocument メソッドを使用して、以前に型指定されていない XML ドキュメントを検証する方法です。 いずれの場合も、検証済みの XML ドキュメントに対して行った変更は、Validate クラスの XmlDocument メソッドを使用して再度検証することができます。

読み込み時のドキュメントの検証

検証型 XmlReader オブジェクトは、XmlReaderSettings オブジェクトをパラメーターとして受け取る Create クラスの XmlReader メソッドに XmlReaderSettings オブジェクトを渡すことで作成できます。 パラメーターとして渡された XmlReaderSettings オブジェクトには、ValidationType が設定された Schema プロパティがあり、XmlDocument オブジェクトに含まれる XML ドキュメントの XML スキーマが Schemas プロパティに追加されています。 検証型 XmlReader オブジェクトは、次に XmlDocument オブジェクトを作成するために使用されます。

次の例では、検証型 contosoBooks.xml オブジェクトを使用して、XmlDocument オブジェクトを作成することにより、XmlDocument ファイルを XmlReader オブジェクトに読み込む際に検証を行います。 この XML ドキュメントはそのスキーマに照らして有効なので、スキーマの検証エラーや警告は何も生成されません。

Imports System  
Imports System.Xml  
Imports System.Xml.Schema  
Imports System.Xml.XPath  
  
Class ValidatingReaderExample  
  
    Shared Sub Main(ByVal args() As String)  
  
        Try  
            Dim settings As XmlReaderSettings = New XmlReaderSettings()  
            settings.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd")  
            settings.ValidationType = ValidationType.Schema  
  
            Dim reader As XmlReader = XmlReader.Create("contosoBooks.xml", settings)  
  
            Dim document As XmlDocument = New XmlDocument()  
            document.Load(reader)  
            Dim navigator As XPathNavigator = document.CreateNavigator()  
  
        Catch e As Exception  
            Console.WriteLine("ValidatingReaderExample.Exception: {0}", e.Message)  
        End Try  
  
    End Sub  
  
    Shared Sub SchemaValidationHandler(ByVal sender As Object, ByVal e As ValidationEventArgs)  
  
        Select Case e.Severity  
            Case XmlSeverityType.Error  
                Console.WriteLine("Schema Validation Error: {0}", e.Message)  
                Exit Sub  
            Case XmlSeverityType.Warning  
                Console.WriteLine("Schema Validation Warning: {0}", e.Message)  
                Exit Sub  
        End Select  
  
    End Sub  
  
End Class  
using System;  
using System.Xml;  
using System.Xml.Schema;  
using System.Xml.XPath;  
  
class ValidatingReaderExample  
{  
    static void Main(string[] args)  
    {  
        try  
        {  
            XmlReaderSettings settings = new XmlReaderSettings();  
            settings.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd");  
            settings.ValidationType = ValidationType.Schema;  
  
            XmlReader reader = XmlReader.Create("contosoBooks.xml", settings);  
  
            XmlDocument document = new XmlDocument();  
            document.Load(reader);  
            XPathNavigator navigator = document.CreateNavigator();  
        }  
        catch (Exception e)  
        {  
            Console.WriteLine("ValidatingReaderExample.Exception: {0}", e.Message);  
        }  
    }  
  
    static void SchemaValidationHandler(object sender, ValidationEventArgs e)  
    {  
        switch (e.Severity)  
        {  
            case XmlSeverityType.Error:  
                Console.WriteLine("Schema Validation Error: {0}", e.Message);  
                break;  
            case XmlSeverityType.Warning:  
                Console.WriteLine("Schema Validation Warning: {0}", e.Message);  
                break;  
        }  
    }  
}  

この例は、contosoBooks.xml ファイルを入力として使用します。

<?xml version="1.0" encoding="utf-8" ?>
<bookstore xmlns="http://www.contoso.com/books">
    <book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
        <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" publicationdate="1967-11-17" ISBN="0-201-63361-2">
        <title>The Confidence Man</title>
        <author>
            <first-name>Herman</first-name>
            <last-name>Melville</last-name>
        </author>
        <price>11.99</price>
    </book>
    <book genre="philosophy" publicationdate="1991-02-15" ISBN="1-861001-57-6">
        <title>The Gorgias</title>
        <author>
            <name>Plato</name>
        </author>
        <price>9.99</price>
    </book>
</bookstore>

また、contosoBooks.xsd ファイルも入力として使用します。

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.contoso.com/books" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="bookstore">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="book">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="title" type="xs:string" />
                            <xs:element name="author">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element minOccurs="0" name="name" type="xs:string" />
                                        <xs:element minOccurs="0" name="first-name" type="xs:string" />
                                        <xs:element minOccurs="0" name="last-name" type="xs:string" />
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                            <xs:element name="price" type="xs:decimal" />
                        </xs:sequence>
                        <xs:attribute name="genre" type="xs:string" use="required" />
                        <xs:attribute name="publicationdate" type="xs:date" use="required" />
                        <xs:attribute name="ISBN" type="xs:string" use="required" />
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

上記の例では、XmlSchemaValidationException を呼び出したときに属性や要素の型が検証スキーマで指定されている型と一致しなかった場合、Load がスローされます。 検証を行う ValidationEventHandlerXmlReader が設定されている場合、無効な型が検出されるたびに ValidationEventHandler が呼び出されます。

XmlSchemaExceptionTypedValue に設定されている属性または要素が invalid によりアクセスされると、XPathNavigator がスローされます。

Validity を使用して属性または要素にアクセスするとき、XPathNavigator プロパティを使用して、個々の属性または要素が有効かどうかを判断できます。

注意

XML ドキュメントが既定値を定義した関連付けられたスキーマと共に XmlDocument オブジェクトに読み込まれる場合、XmlDocument オブジェクトは、これらの既定値があたかも XML ドキュメント内にあるかのように扱います。 これは、XML ドキュメントで空要素として書かれていても、スキーマから既定値を得た要素に対して IsEmptyElement プロパティは常に false を返すことを意味します。

Validate メソッドを使用したドキュメントの検証

Validate クラスの XmlDocument メソッドは、XmlDocument オブジェクトの XmlDocument プロパティで指定されたスキーマに対して、Schemas オブジェクトに含まれる XML ドキュメントを検証し、情報セットの拡大を実施します。 結果として、XmlDocument オブジェクト中の以前は型指定されていない XML ドキュメントは型指定されたドキュメントに置き換わります。

XmlDocument オブジェクトは、ValidationEventHandler メソッドへのパラメーターとして渡された Validate デリゲートを使用してスキーマ検証のエラーと警告を報告します。

次の例では、contosoBooks.xml オブジェクトの XmlDocument プロパティに含まれる contosoBooks.xsd スキーマに対して、XmlDocument オブジェクトに含まれる Schemas ファイルを検証します。

Imports System  
Imports System.Xml  
Imports System.Xml.Schema  
Imports System.Xml.XPath  
  
Class ValidateExample  
  
    Shared Sub Main(ByVal args() As String)  
  
        Dim document As XmlDocument = New XmlDocument()  
        document.Load("contosoBooks.xml")  
        Dim navigator As XPathNavigator = document.CreateNavigator()  
  
        document.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd")  
        Dim validation As ValidationEventHandler = New ValidationEventHandler(AddressOf SchemaValidationHandler)  
  
        document.Validate(validation)  
  
    End Sub  
  
    Shared Sub SchemaValidationHandler(ByVal sender As Object, ByVal e As ValidationEventArgs)  
  
        Select Case e.Severity  
            Case XmlSeverityType.Error  
                Console.WriteLine("Schema Validation Error: {0}", e.Message)  
                Exit Sub  
            Case XmlSeverityType.Warning  
                Console.WriteLine("Schema Validation Warning: {0}", e.Message)  
                Exit Sub  
        End Select  
  
    End Sub  
  
End Class  
using System;  
using System.Xml;  
using System.Xml.Schema;  
using System.Xml.XPath;  
  
class ValidateExample  
{  
    static void Main(string[] args)  
    {  
        XmlDocument document = new XmlDocument();  
        document.Load("contosoBooks.xml");  
        XPathNavigator navigator = document.CreateNavigator();  
  
        document.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd");  
        ValidationEventHandler validation = new ValidationEventHandler(SchemaValidationHandler);  
  
        document.Validate(validation);  
    }  
  
    static void SchemaValidationHandler(object sender, ValidationEventArgs e)  
    {  
        switch (e.Severity)  
        {  
            case XmlSeverityType.Error:  
                Console.WriteLine("Schema Validation Error: {0}", e.Message);  
                break;  
            case XmlSeverityType.Warning:  
                Console.WriteLine("Schema Validation Warning: {0}", e.Message);  
                break;  
        }  
    }  
}  

この例は、contosoBooks.xml ファイルを入力として使用します。

<?xml version="1.0" encoding="utf-8" ?>
<bookstore xmlns="http://www.contoso.com/books">
    <book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
        <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" publicationdate="1967-11-17" ISBN="0-201-63361-2">
        <title>The Confidence Man</title>
        <author>
            <first-name>Herman</first-name>
            <last-name>Melville</last-name>
        </author>
        <price>11.99</price>
    </book>
    <book genre="philosophy" publicationdate="1991-02-15" ISBN="1-861001-57-6">
        <title>The Gorgias</title>
        <author>
            <name>Plato</name>
        </author>
        <price>9.99</price>
    </book>
</bookstore>

また、contosoBooks.xsd ファイルも入力として使用します。

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.contoso.com/books" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="bookstore">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="book">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="title" type="xs:string" />
                            <xs:element name="author">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element minOccurs="0" name="name" type="xs:string" />
                                        <xs:element minOccurs="0" name="first-name" type="xs:string" />
                                        <xs:element minOccurs="0" name="last-name" type="xs:string" />
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                            <xs:element name="price" type="xs:decimal" />
                        </xs:sequence>
                        <xs:attribute name="genre" type="xs:string" use="required" />
                        <xs:attribute name="publicationdate" type="xs:date" use="required" />
                        <xs:attribute name="ISBN" type="xs:string" use="required" />
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

変更点の検証

XML ドキュメントに変更が施された後、Validate クラスの XmlDocument メソッドを使用して、変更点を XML ドキュメントのスキーマに対して検証できます。

次の例では、検証型 contosoBooks.xml オブジェクトを使用して、XmlDocument オブジェクトを作成することにより、XmlDocument ファイルを XmlReader オブジェクトに読み込む際に検証を行います。 XML ドキュメントは、スキーマ検証のエラーや警告を生成せずに、読み込み時に問題なく検証されます。 次に、この例で contosoBooks.xsd スキーマに従うと無効な 2 つの変更が XML ドキュメントに施されます。 最初の変更点は、無効な子要素を挿入してスキーマ検証エラーを引き起こします。2 番目の変更点は、型指定されたノードにノードの型に反して無効な値を設定し、例外が発生します。

Imports System  
Imports System.Xml  
Imports System.Xml.Schema  
Imports System.Xml.XPath  
  
Class ValidatingReaderExample  
  
    Shared Sub Main(ByVal args() As String)  
  
        Try  
            Dim settings As XmlReaderSettings = New XmlReaderSettings()  
            settings.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd")  
            settings.ValidationType = ValidationType.Schema  
  
            Dim reader As XmlReader = XmlReader.Create("contosoBooks.xml", settings)  
  
            Dim document As XmlDocument = New XmlDocument()  
            document.Load(reader)  
            Dim navigator As XPathNavigator = document.CreateNavigator()  
  
            Dim validation As ValidationEventHandler = New ValidationEventHandler(AddressOf SchemaValidationHandler)  
  
            navigator.MoveToChild("bookstore", "http://www.contoso.com/books")  
            navigator.MoveToChild("book", "http://www.contoso.com/books")  
            navigator.MoveToChild("author", "http://www.contoso.com/books")  
  
            navigator.AppendChild("<title>Book Title</title>")  
  
            document.Validate(validation)  
  
            navigator.MoveToParent()  
            navigator.MoveToChild("price", "http://www.contoso.com/books")  
            navigator.SetTypedValue(DateTime.Now)  
        Catch e As Exception  
            Console.WriteLine("ValidatingReaderExample.Exception: {0}", e.Message)  
        End Try  
  
    End Sub  
  
    Shared Sub SchemaValidationHandler(ByVal sender As Object, ByVal e As ValidationEventArgs)  
  
        Select Case e.Severity  
            Case XmlSeverityType.Error  
                Console.WriteLine("Schema Validation Error: {0}", e.Message)  
                Exit Sub  
            Case XmlSeverityType.Warning  
                Console.WriteLine("Schema Validation Warning: {0}", e.Message)  
                Exit Sub  
        End Select  
  
    End Sub  
  
End Class  
using System;  
using System.Xml;  
using System.Xml.Schema;  
using System.Xml.XPath;  
  
class ValidatingReaderExample  
{  
    static void Main(string[] args)  
    {  
        try  
        {  
            XmlReaderSettings settings = new XmlReaderSettings();  
            settings.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd");  
            settings.ValidationType = ValidationType.Schema;  
  
            XmlReader reader = XmlReader.Create("contosoBooks.xml", settings);  
  
            XmlDocument document = new XmlDocument();  
            document.Load(reader);  
            XPathNavigator navigator = document.CreateNavigator();  
  
            ValidationEventHandler validation = new ValidationEventHandler(SchemaValidationHandler);  
  
            navigator.MoveToChild("bookstore", "http://www.contoso.com/books");  
            navigator.MoveToChild("book", "http://www.contoso.com/books");  
            navigator.MoveToChild("author", "http://www.contoso.com/books");  
  
            navigator.AppendChild("<title>Book Title</title>");  
  
            document.Validate(validation);  
  
            navigator.MoveToParent();  
            navigator.MoveToChild("price", "http://www.contoso.com/books");  
            navigator.SetTypedValue(DateTime.Now);  
        }  
        catch (Exception e)  
        {  
            Console.WriteLine("ValidatingReaderExample.Exception: {0}", e.Message);  
        }  
    }  
  
    static void SchemaValidationHandler(object sender, ValidationEventArgs e)  
    {  
        switch (e.Severity)  
        {  
            case XmlSeverityType.Error:  
                Console.WriteLine("Schema Validation Error: {0}", e.Message);  
                break;  
            case XmlSeverityType.Warning:  
                Console.WriteLine("Schema Validation Warning: {0}", e.Message);  
                break;  
        }  
    }  
}  

この例は、contosoBooks.xml ファイルを入力として使用します。

<?xml version="1.0" encoding="utf-8" ?>
<bookstore xmlns="http://www.contoso.com/books">
    <book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
        <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" publicationdate="1967-11-17" ISBN="0-201-63361-2">
        <title>The Confidence Man</title>
        <author>
            <first-name>Herman</first-name>
            <last-name>Melville</last-name>
        </author>
        <price>11.99</price>
    </book>
    <book genre="philosophy" publicationdate="1991-02-15" ISBN="1-861001-57-6">
        <title>The Gorgias</title>
        <author>
            <name>Plato</name>
        </author>
        <price>9.99</price>
    </book>
</bookstore>

また、contosoBooks.xsd ファイルも入力として使用します。

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.contoso.com/books" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="bookstore">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="book">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="title" type="xs:string" />
                            <xs:element name="author">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element minOccurs="0" name="name" type="xs:string" />
                                        <xs:element minOccurs="0" name="first-name" type="xs:string" />
                                        <xs:element minOccurs="0" name="last-name" type="xs:string" />
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                            <xs:element name="price" type="xs:decimal" />
                        </xs:sequence>
                        <xs:attribute name="genre" type="xs:string" use="required" />
                        <xs:attribute name="publicationdate" type="xs:date" use="required" />
                        <xs:attribute name="ISBN" type="xs:string" use="required" />
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

上の例では、XmlDocument オブジェクトに含まれる XML ドキュメントに 2 つの変更が施されます。 XML ドキュメントが読み込まれるに従い、発見されたスキーマ検証エラーは検証イベント ハンドラー メソッドで処理され、コンソールに書き出されました。

この例では、XML ドキュメントが読み込まれた後に検証エラーが挿入され、Validate クラスの XmlDocument メソッドを使用して発見されました。

SetTypedValue クラスの XPathNavigator メソッドを使用して行われた変更は、新しい値がノードのスキーマ型に照らして無効だったので、InvalidCastException が発生しました。

SetTypedValue メソッドを使用して値を変更する方法の詳細については、「XpathNavigator による XML データの変更」のトピックを参照してください。

読み取り専用の検証

XPathDocument クラスは、XML ドキュメントの読み取り専用のメモリ内表現です。 XPathDocument クラスと XmlDocument クラスは両方とも、XML ドキュメントを編集しナビゲートするために XPathNavigator オブジェクトを作成します。 XPathDocument クラスは読み取り専用のクラスなので、XPathNavigator オブジェクトから返された XPathDocument オブジェクトは XPathDocument オブジェクトに含まれる XML ドキュメントを編集できません。

このトピックで前述したように、検証の場合は、検証型 XPathDocument オブジェクトを使用して XmlDocument オブジェクトを作成したのと同様にして、XmlReader オブジェクトを作成できます。 XPathDocument オブジェクトは読み込みの際に XML ドキュメントを検証しますが、XPathDocument オブジェクト内の XML データは編集できないので、XML ドキュメントの再検証はできません。

読み取り専用および編集可能な XPathNavigator オブジェクトについては、「XPathDocument および XmlDocument を使用した XML データの読み取り」のトピックを参照してください。

関連項目