次の方法で共有


DOM で XML ドキュメントを検証する

XmlDocument クラスは、ドキュメント オブジェクト モデル (DOM) の XML を XML スキーマ定義言語 (XSD) スキーマまたはドキュメント型定義 (DTD) に対して既定では検証しません。XML は整形式であることが確認されるだけです。

DOM 内の XML を検証するには、XmlReader クラスのLoad メソッドにスキーマ検証XmlDocumentを渡すことによって、DOM に読み込まれる XML を検証するか、Validate クラスのXmlDocument メソッドを使用して DOM 内の以前に検証されていない XML ドキュメントを検証します。

DOM に読み込まれる XML ドキュメントの検証

XmlDocument クラスは、XmlReader クラスのLoad メソッドに検証XmlDocumentが渡されるときに、XML データが DOM に読み込まれるときに検証します。

検証が成功すると、スキーマの既定値が適用され、必要に応じてテキスト値がアトミック値に変換され、型情報が検証済みの情報項目に関連付けられます。 その結果、型指定された XML データは、以前に型指定されていない XML データに置き換えられます。

XmlReader Schema-Validating XML の作成

XML スキーマ検証 XmlReaderを作成するには、次の手順に従います。

  1. 新しい XmlReaderSettings インスタンスを構築します。

  2. Schemas インスタンスの XmlReaderSettings プロパティに XML スキーマを追加します。

  3. SchemaとしてValidationTypeを指定します。

  4. 必要に応じて、 ValidationFlags と、検証中に発生したスキーマ検証エラーと警告を処理する ValidationEventHandler を指定します。

  5. 最後に、xml ドキュメントと共にXmlReaderSettings クラスのCreate メソッドにXmlReader オブジェクトを渡し、スキーマ検証XmlReaderを作成します。

次のコード例では、スキーマ検証 XmlReader は、DOM に読み込まれた XML データを検証します。 XML ドキュメントに無効な変更が加えられた後、ドキュメントが再検証され、スキーマ検証エラーが発生します。 最後に、エラーの 1 つが修正され、XML ドキュメントの一部が部分的に検証されます。

using System;
using System.Xml;
using System.Xml.Schema;

class XmlDocumentValidationExample
{
    static void Main(string[] args)
    {
        try
        {
            // Create a schema validating XmlReader.
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd");
            settings.ValidationEventHandler += new ValidationEventHandler(ValidationEventHandler);
            settings.ValidationFlags = settings.ValidationFlags | XmlSchemaValidationFlags.ReportValidationWarnings;
            settings.ValidationType = ValidationType.Schema;

            XmlReader reader = XmlReader.Create("contosoBooks.xml", settings);

            // The XmlDocument validates the XML document contained
            // in the XmlReader as it is loaded into the DOM.
            XmlDocument document = new XmlDocument();
            document.Load(reader);

            // Make an invalid change to the first and last
            // price elements in the XML document, and write
            // the XmlSchemaInfo values assigned to the price
            // element during load validation to the console.
            XmlNamespaceManager manager = new XmlNamespaceManager(document.NameTable);
            manager.AddNamespace("bk", "http://www.contoso.com/books");

            XmlNode priceNode = document.SelectSingleNode(@"/bk:bookstore/bk:book/bk:price", manager);

            Console.WriteLine($"SchemaInfo.IsDefault: {priceNode.SchemaInfo.IsDefault}");
            Console.WriteLine($"SchemaInfo.IsNil: {priceNode.SchemaInfo.IsNil}");
            Console.WriteLine($"SchemaInfo.SchemaElement: {priceNode.SchemaInfo.SchemaElement}");
            Console.WriteLine($"SchemaInfo.SchemaType: {priceNode.SchemaInfo.SchemaType}");
            Console.WriteLine($"SchemaInfo.Validity: {priceNode.SchemaInfo.Validity}");

            priceNode.InnerXml = "A";

            XmlNodeList priceNodes = document.SelectNodes(@"/bk:bookstore/bk:book/bk:price", manager);
            XmlNode lastprice = priceNodes[priceNodes.Count - 1];

            lastprice.InnerXml = "B";

            // Validate the XML document with the invalid changes.
            // The invalid changes cause schema validation errors.
            document.Validate(ValidationEventHandler);

            // Correct the invalid change to the first price element.
            priceNode.InnerXml = "8.99";

            // Validate only the first book element. The last book
            // element is invalid, but not included in validation.
            XmlNode bookNode = document.SelectSingleNode(@"/bk:bookstore/bk:book", manager);
            document.Validate(ValidationEventHandler, bookNode);
        }
        catch (XmlException ex)
        {
            Console.WriteLine($"XmlDocumentValidationExample.XmlException: {ex.Message}");
        }
        catch(XmlSchemaValidationException ex)
        {
            Console.WriteLine($"XmlDocumentValidationExample.XmlSchemaValidationException: {ex.Message}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"XmlDocumentValidationExample.Exception: {ex.Message}");
        }
    }

    static void ValidationEventHandler(object sender, System.Xml.Schema.ValidationEventArgs args)
    {
        if (args.Severity == XmlSeverityType.Warning)
            Console.Write("\nWARNING: ");
        else if (args.Severity == XmlSeverityType.Error)
            Console.Write("\nERROR: ");

        Console.WriteLine(args.Message);
    }
}
Imports System.Xml
Imports System.Xml.Schema

Class XmlDocumentValidationExample

    Shared Sub Main()

        Try

            ' Create a schema validating XmlReader.
            Dim settings As XmlReaderSettings = New XmlReaderSettings()
            settings.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd")
            AddHandler settings.ValidationEventHandler, New ValidationEventHandler(AddressOf ValidationEventHandler)
            settings.ValidationFlags = settings.ValidationFlags And XmlSchemaValidationFlags.ReportValidationWarnings
            settings.ValidationType = ValidationType.Schema

            Dim reader As XmlReader = XmlReader.Create("contosoBooks.xml", settings)

            ' The XmlDocument validates the XML document contained
            ' in the XmlReader as it is loaded into the DOM.
            Dim document As XmlDocument = New XmlDocument()
            document.Load(reader)

            ' Make an invalid change to the first and last 
            ' price elements in the XML document, and write
            ' the XmlSchemaInfo values assigned to the price
            ' element during load validation to the console.
            Dim manager As XmlNamespaceManager = New XmlNamespaceManager(document.NameTable)
            manager.AddNamespace("bk", "http://www.contoso.com/books")

            Dim priceNode As XmlNode = document.SelectSingleNode("/bk:bookstore/bk:book/bk:price", manager)

            Console.WriteLine("SchemaInfo.IsDefault: {0}", priceNode.SchemaInfo.IsDefault)
            Console.WriteLine("SchemaInfo.IsNil: {0}", priceNode.SchemaInfo.IsNil)
            Console.WriteLine("SchemaInfo.SchemaElement: {0}", priceNode.SchemaInfo.SchemaElement)
            Console.WriteLine("SchemaInfo.SchemaType: {0}", priceNode.SchemaInfo.SchemaType)
            Console.WriteLine("SchemaInfo.Validity: {0}", priceNode.SchemaInfo.Validity)

            priceNode.InnerXml = "A"

            Dim priceNodes As XmlNodeList = document.SelectNodes("/bk:bookstore/bk:book/bk:price", manager)
            Dim lastprice As XmlNode = priceNodes(priceNodes.Count - 1)

            lastprice.InnerXml = "B"

            ' Validate the XML document with the invalid changes.
            ' The invalid changes cause schema validation errors.
            document.Validate(AddressOf ValidationEventHandler)

            ' Correct the invalid change to the first price element.
            priceNode.InnerXml = "8.99"

            ' Validate only the first book element. The last book
            ' element is invalid, but not included in validation.
            Dim bookNode As XmlNode = document.SelectSingleNode("/bk:bookstore/bk:book", manager)
            document.Validate(AddressOf ValidationEventHandler, bookNode)

        Catch ex As XmlException
            Console.WriteLine("XmlDocumentValidationExample.XmlException: {0}", ex.Message)

        Catch ex As XmlSchemaValidationException
            Console.WriteLine("XmlDocumentValidationExample.XmlSchemaValidationException: {0}", ex.Message)

        Catch ex As Exception
            Console.WriteLine("XmlDocumentValidationExample.Exception: {0}", ex.Message)

        End Try

    End Sub

    Shared Sub ValidationEventHandler(ByVal sender As Object, ByVal args As ValidationEventArgs)

        If args.Severity = XmlSeverityType.Warning Then
            Console.Write(vbCrLf & "WARNING: ")
        Else
            If args.Severity = XmlSeverityType.Error Then
                Console.Write(vbCrLf & "ERROR: ")
            End If
        End If
        Console.WriteLine(args.Message)

    End Sub

End Class

この例では、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>

DOM に読み込まれる XML データを検証するときは、次の点を考慮してください。

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

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

DOM での XML ドキュメントの検証

Validate クラスの XmlDocument メソッドは、DOM に読み込まれた XML データを、XmlDocument オブジェクトのSchemas プロパティ内のスキーマと照合して検証します。 検証が成功すると、スキーマの既定値が適用され、必要に応じてテキスト値がアトミック値に変換され、型情報が検証済みの情報項目に関連付けられます。 その結果、型指定された XML データは、以前に型指定されていない XML データに置き換えられます。

次の例は、上記の「XML ドキュメントの DOM への読み込み時の検証」の例に似ています。 この例では、XML ドキュメントは DOM に読み込まれるため検証されませんが、Validate クラスの XmlDocument メソッドを使用して DOM に読み込まれた後で検証されます。 Validate メソッドは、SchemasXmlDocument プロパティに含まれる XML スキーマに対して XML ドキュメントを検証します。 XML ドキュメントに無効な変更が加えられた後、ドキュメントが再検証され、スキーマ検証エラーが発生します。 最後に、エラーの 1 つが修正され、XML ドキュメントの一部が部分的に検証されます。

using System;
using System.Xml;
using System.Xml.Schema;

class XmlDocumentValidationExample
{
    static void Main(string[] args)
    {
        try
        {
            // Create a new XmlDocument instance and load
            // the XML document into the DOM.
            XmlDocument document = new XmlDocument();
            document.Load("contosoBooks.xml");

            // Add the XML schema for the XML document to the
            // Schemas property of the XmlDocument.
            document.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd");

            // Validate the XML document loaded into the DOM.
            document.Validate(ValidationEventHandler);

            // Make an invalid change to the first and last
            // price elements in the XML document, and write
            // the XmlSchemaInfo values assigned to the price
            // element during validation to the console.
            XmlNamespaceManager manager = new XmlNamespaceManager(document.NameTable);
            manager.AddNamespace("bk", "http://www.contoso.com/books");

            XmlNode priceNode = document.SelectSingleNode(@"/bk:bookstore/bk:book/bk:price", manager);

            Console.WriteLine($"SchemaInfo.IsDefault: {priceNode.SchemaInfo.IsDefault}");
            Console.WriteLine($"SchemaInfo.IsNil: {priceNode.SchemaInfo.IsNil}");
            Console.WriteLine($"SchemaInfo.SchemaElement: {priceNode.SchemaInfo.SchemaElement}");
            Console.WriteLine($"SchemaInfo.SchemaType: {priceNode.SchemaInfo.SchemaType}");
            Console.WriteLine($"SchemaInfo.Validity: {priceNode.SchemaInfo.Validity}");

            priceNode.InnerXml = "A";

            XmlNodeList priceNodes = document.SelectNodes(@"/bk:bookstore/bk:book/bk:price", manager);
            XmlNode lastprice = priceNodes[priceNodes.Count - 1];

            lastprice.InnerXml = "B";

            // Validate the XML document with the invalid changes.
            // The invalid changes cause schema validation errors.
            document.Validate(ValidationEventHandler);

            // Correct the invalid change to the first price element.
            priceNode.InnerXml = "8.99";

            // Validate only the first book element. The last book
            // element is invalid, but not included in validation.
            XmlNode bookNode = document.SelectSingleNode(@"/bk:bookstore/bk:book", manager);
            document.Validate(ValidationEventHandler, bookNode);
        }
        catch (XmlException ex)
        {
            Console.WriteLine($"XmlDocumentValidationExample.XmlException: {ex.Message}");
        }
        catch(XmlSchemaValidationException ex)
        {
            Console.WriteLine($"XmlDocumentValidationExample.XmlSchemaValidationException: {ex.Message}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"XmlDocumentValidationExample.Exception: {ex.Message}");
        }
    }

    static void ValidationEventHandler(object sender, System.Xml.Schema.ValidationEventArgs args)
    {
        if (args.Severity == XmlSeverityType.Warning)
            Console.Write("\nWARNING: ");
        else if (args.Severity == XmlSeverityType.Error)
            Console.Write("\nERROR: ");

        Console.WriteLine(args.Message);
    }
}
Imports System.Xml
Imports System.Xml.Schema

Class XmlDocumentValidationExample

    Shared Sub Main()

        Try

            ' Create a new XmlDocument instance and load
            ' the XML document into the DOM.
            Dim document As XmlDocument = New XmlDocument()
            document.Load("contosoBooks.xml")

            ' Add the XML schema for the XML document to the
            ' Schemas property of the XmlDocument.
            document.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd")

            ' Validate the XML document loaded into the DOM.
            document.Validate(AddressOf ValidationEventHandler)

            ' Make an invalid change to the first and last 
            ' price elements in the XML document, and write
            ' the XmlSchemaInfo values assigned to the price
            ' element during validation to the console.
            Dim manager As XmlNamespaceManager = New XmlNamespaceManager(document.NameTable)
            manager.AddNamespace("bk", "http://www.contoso.com/books")

            Dim priceNode As XmlNode = document.SelectSingleNode("/bk:bookstore/bk:book/bk:price", manager)

            Console.WriteLine("SchemaInfo.IsDefault: {0}", priceNode.SchemaInfo.IsDefault)
            Console.WriteLine("SchemaInfo.IsNil: {0}", priceNode.SchemaInfo.IsNil)
            Console.WriteLine("SchemaInfo.SchemaElement: {0}", priceNode.SchemaInfo.SchemaElement)
            Console.WriteLine("SchemaInfo.SchemaType: {0}", priceNode.SchemaInfo.SchemaType)
            Console.WriteLine("SchemaInfo.Validity: {0}", priceNode.SchemaInfo.Validity)

            priceNode.InnerXml = "A"

            Dim priceNodes As XmlNodeList = document.SelectNodes("/bk:bookstore/bk:book/bk:price", manager)
            Dim lastprice As XmlNode = priceNodes(priceNodes.Count - 1)

            lastprice.InnerXml = "B"

            ' Validate the XML document with the invalid changes.
            ' The invalid changes cause schema validation errors.
            document.Validate(AddressOf ValidationEventHandler)

            ' Correct the invalid change to the first price element.
            priceNode.InnerXml = "8.99"

            ' Validate only the first book element. The last book
            ' element is invalid, but not included in validation.
            Dim bookNode As XmlNode = document.SelectSingleNode("/bk:bookstore/bk:book", manager)
            document.Validate(AddressOf ValidationEventHandler, bookNode)

        Catch ex As XmlException
            Console.WriteLine("XmlDocumentValidationExample.XmlException: {0}", ex.Message)

        Catch ex As XmlSchemaValidationException
            Console.WriteLine("XmlDocumentValidationExample.XmlSchemaValidationException: {0}", ex.Message)

        Catch ex As Exception
            Console.WriteLine("XmlDocumentValidationExample.Exception: {0}", ex.Message)

        End Try

    End Sub

    Shared Sub ValidationEventHandler(ByVal sender As Object, ByVal args As ValidationEventArgs)

        If args.Severity = XmlSeverityType.Warning Then
            Console.Write(vbCrLf & "WARNING: ")
        Else
            If args.Severity = XmlSeverityType.Error Then
                Console.Write(vbCrLf & "ERROR: ")
            End If
        End If
        Console.WriteLine(args.Message)

    End Sub

End Class

この例では、上記の「XML ドキュメントを DOM に読み込む際の検証」で参照されている contosoBooks.xml ファイルと contosoBooks.xsd ファイルを入力として受け取ります。

検証エラーと警告の処理

XML スキーマ検証エラーは、DOM に読み込まれた XML データを検証するときに報告されます。 読み込み中の XML データの検証中、または以前に検証されていない XML ドキュメントの検証中に検出されたすべてのスキーマ検証エラーが通知されます。

検証エラーは、 ValidationEventHandlerによって処理されます。 ValidationEventHandlerXmlReaderSettings インスタンスに割り当てられた場合、またはValidate クラスのXmlDocument メソッドに渡された場合、ValidationEventHandlerはスキーマ検証エラーを処理します。それ以外の場合は、スキーマ検証エラーが発生したときにXmlSchemaValidationExceptionが発生します。

プロセスを停止する例外が ValidationEventHandler によって発生しない限り、スキーマ検証エラーが発生した場合でも、XML データは DOM に読み込まれます。

ReportValidationWarnings オブジェクトにXmlReaderSettings フラグが指定されていない限り、スキーマ検証の警告は報告されません。

ValidationEventHandlerを示す例については、上記の「DOM に読み込まれる XML ドキュメントの検証」および「DOM での XML ドキュメントの検証」を参照してください。

こちらも参照ください