XPathNavigator를 사용하여 스키마 유효성 검사

XmlDocument 클래스를 사용하면 두 가지 방법으로 XmlDocument 개체에 포함된 XML 내용의 유효성을 검사할 수 있습니다. 첫 번째 방법은 유효성 검사 XmlReader 개체를 사용하여 XML 내용의 유효성을 검사하는 것이고 두 번째 방법은 Validate 클래스의 XmlDocument 메서드를 사용하는 것입니다. XPathDocument 클래스를 사용하여 XML 내용의 읽기 전용 유효성 검사를 수행할 수도 있습니다.

XML 데이터 유효성 검사

기본적으로 XmlDocument 클래스는 DTD나 XSD(XML 스키마 정의 언어) 스키마 유효성 검사를 통해 XML 문서의 유효성을 검사하지 않으며 XML 문서가 제대로 구성되었는지만 확인합니다.

XML 문서의 유효성을 검사하는 첫 번째 방법은 유효성을 검사하는 XmlDocument 개체를 사용하여 XmlReader 개체로 XML 문서를 로드할 때 유효성을 검사하는 것입니다. 두 번째 방법은 Validate 클래스의 XmlDocument 메서드를 사용하여 이전에 형식화한 XML 문서의 유효성을 검사하는 것입니다. 두 가지 경우 모두 유효성을 검사한 XML 문서의 변경 내용에 대해 Validate 클래스의 XmlDocument 메서드를 사용하여 유효성을 다시 검사할 수 있습니다.

문서를 로드할 때 유효성 검사

XmlReader 개체를 매개 변수로 사용하는 XmlReaderSettings 클래스의 Create 메서드에 XmlReader 개체를 전달하면 유효성을 검사하는 XmlReaderSettings 개체가 만들어집니다. 매개 변수로 전달된 XmlReaderSettings 개체의 ValidationType 속성은 Schema로 설정되어 있으며 XmlDocument 속성에 추가된 Schemas 개체에 XML 문서의 XML 스키마가 포함되어 있습니다. 그러면 유효성을 검사하는 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이 throw됩니다. ValidationEventHandler 유효성 검사에 XmlReader가 설정된 경우 잘못된 형식이 발견될 때마다 ValidationEventHandler가 호출됩니다.

XmlSchemaExceptionTypedValue로 설정된 특성 또는 요소를 invalid에서 액세스하는 경우 XPathNavigator이 throw됩니다.

Validity로 특성 또는 요소에 액세스할 때 XPathNavigator 속성을 사용하여 개별 특성 또는 요소가 유효한지 여부를 확인할 수 있습니다.

참고 항목

기본값을 정의하는 스키마가 연결되어 있는 XML 문서를 XmlDocument 개체에 로드하면 XmlDocument 개체는 이 기본값이 XML 문서에 나타난 것처럼 처리합니다. 그러므로 빈 요소로 쓰여진 XML 문서에서도 IsEmptyElement 속성은 스키마에서 기본값으로 설정된 요소에 대해 항상 false를 반환합니다.

Validate 메서드를 사용하여 문서의 유효성 검사

Validate 클래스의 XmlDocument 메서드는 XmlDocument 개체의 XmlDocument 속성에 지정된 스키마에 대해 Schemas 개체에 포함된 XML 문서의 유효성을 검사하고 Infoset 확대를 수행합니다. 그 결과 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 스키마에 따라 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()  
  
            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 문서에서 두 가지 사항을 수정했습니다. XML 문서를 로드할 때 발생한 스키마 유효성 검사 오류는 유효성 검사 이벤트 처리기 메서드에 의해 처리되고 콘솔에 기록됩니다.

이 예제에서는 XML 문서를 로드한 후 유효성 검사 오류가 발생했으며 Validate 클래스의 XmlDocument 메서드를 사용하여 오류가 발견되었습니다.

노드의 스키마 형식에 따르면 새 값이 유효하지 않기 때문에 SetTypedValue 클래스의 XPathNavigator 메서드를 사용하여 수정한 사항으로 인해 InvalidCastException이 발생했습니다.

SetTypedValue 메서드를 사용하여 값을 수정하는 방법에 대한 자세한 내용은 XPathNavigator를 사용하여 XML 데이터 수정 항목을 참조하세요.

읽기 전용 유효성 검사

XPathDocument 클래스는 읽기 전용 메모리 내 XML 문서 표현입니다. XPathDocument 클래스와 XmlDocument 클래스는 XPathNavigator 개체를 만들어 XML 문서를 탐색하고 편집합니다. XPathDocument 클래스는 읽기 전용 클래스이므로 XPathNavigator 개체에서 반환된 XPathDocument 개체는 XPathDocument 개체에 포함된 XML 문서를 편집할 수 없습니다.

유효성 검사의 경우 이 항목의 앞부분에서 설명한 대로 유효성을 검사하는 XPathDocument 개체를 사용하여 XmlDocument 개체를 만든 것과 같이 XmlReader 개체를 만들 수 있습니다. XPathDocument 개체는 XML 문서를 로드할 때 이 문서의 유효성을 검사하지만 XPathDocument 개체에서 XML 데이터를 편집할 수 없으므로 XML 문서의 유효성을 다시 검사할 수 없습니다.

읽기 전용 및 편집 가능한 XPathNavigator 개체에 대한 자세한 내용은 XPathDocument 및 XmlDocument를 사용하여 XML 데이터 읽기 항목을 참조하세요.

참고 항목