XPathNavigator를 사용하여 스키마 유효성 검사
업데이트: November 2007
XmlDocument 클래스를 사용하면 두 가지 방법으로 XmlDocument 개체에 포함된 XML 내용의 유효성을 검사할 수 있습니다. 첫 번째 방법은 유효성 검사 XmlReader 개체를 사용하여 XML 내용의 유효성을 검사하는 것이고 두 번째 방법은 XmlDocument 클래스의 Validate 메서드를 사용하는 것입니다. XPathDocument 클래스를 사용하여 XML 내용의 읽기 전용 유효성 검사를 수행할 수도 있습니다.
XML 데이터 유효성 검사
기본적으로 XmlDocument 클래스는 DTD나 XSD(XML 스키마 정의 언어) 스키마 유효성 검사를 통해 XML 문서의 유효성을 검사하지 않으며 XML 문서가 제대로 구성되었는지만 확인합니다.
XML 문서의 유효성을 검사하는 첫 번째 방법은 유효성을 검사하는 XmlReader 개체를 사용하여 XmlDocument 개체로 XML 문서를 로드할 때 유효성을 검사하는 것입니다. 두 번째 방법은 XmlDocument 클래스의 Validate 메서드를 사용하여 이전에 형식화한 XML 문서의 유효성을 검사하는 것입니다. 두 가지 경우 모두 유효성을 검사한 XML 문서의 변경 내용에 대해 XmlDocument 클래스의 Validate 메서드를 사용하여 유효성을 다시 검사할 수 있습니다.
문서를 로드할 때 유효성 검사
XmlReaderSettings 개체를 매개 변수로 사용하는 XmlReader 클래스의 Create 메서드에 XmlReaderSettings 개체를 전달하면 유효성을 검사하는 XmlReader 개체가 만들어집니다. 매개 변수로 전달된 XmlReaderSettings 개체의 ValidationType 속성은 Schema로 설정되어 있으며 Schemas 속성에 추가된 XmlDocument 개체에 XML 문서의 XML 스키마가 포함되어 있습니다. 그러면 유효성을 검사하는 XmlReader 개체를 사용하여 XmlDocument 개체를 만들 수 있습니다.
다음 예제에서는 XmlReader 개체의 유효성 검사를 통해 XmlDocument 개체를 만들어 contosoBooks.xml 파일이 XmlDocument 개체로 로드되면 해당 파일의 유효성을 검사합니다. 해당 스키마에 따르면 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("https://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("https://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 파일을 입력으로 사용합니다.
<bookstore xmlns="https://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="https://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>
위 예제에서 Load가 호출될 때 특성 또는 요소 형식이 유효성 검사 스키마에 지정된 해당 형식과 일치하지 않으면 XmlSchemaValidationException이 throw됩니다. XmlReader 유효성 검사에 ValidationEventHandler가 설정된 경우 잘못된 형식이 발견될 때마다 ValidationEventHandler가 호출됩니다.
TypedValue가 invalid로 설정된 특성 또는 요소를 XPathNavigator에서 액세스하는 경우 XmlSchemaException이 throw됩니다.
XPathNavigator로 특성 또는 요소에 액세스할 때 Validity 속성을 사용하여 개별 특성 또는 요소가 유효한지 여부를 확인할 수 있습니다.
참고: |
---|
기본값을 정의하는 스키마가 연결되어 있는 XML 문서를 XmlDocument 개체에 로드하면 XmlDocument 개체는 이 기본값이 XML 문서에 나타난 것처럼 처리합니다. 그러므로 빈 요소로 쓰여진 XML 문서에서도 IsEmptyElement 속성은 스키마에서 기본값으로 설정된 요소에 대해 항상 false를 반환합니다. |
Validate 메서드를 사용하여 문서의 유효성 검사
XmlDocument 클래스의 Validate 메서드는 XmlDocument 개체의 Schemas 속성에 지정된 스키마에 대해 XmlDocument 개체에 포함된 XML 문서의 유효성을 검사하고 Infoset 확대를 수행합니다. 그 결과 XmlDocument 개체에서 이전에 형식화하지 않은 XML 문서가 형식화된 문서로 바뀝니다.
XmlDocument 개체는 Validate 메서드에 매개 변수로 전달된 ValidationEventHandler 대리자를 사용하여 스키마 유효성 검사 오류 및 경고를 보고합니다.
다음 예제에서는 XmlDocument 개체의 Schemas 속성에 포함된 contosoBooks.xsd 스키마에 대해 XmlDocument 개체에 포함된 contosoBooks.xml 파일의 유효성을 검사합니다.
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("https://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("https://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 파일을 입력으로 사용합니다.
<bookstore xmlns="https://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="https://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 문서를 수정한 후 XmlDocument 클래스의 Validate 메서드를 사용하여 XML 문서의 스키마에 대해 수정 내용의 유효성을 검사할 수 있습니다.
다음 예제에서는 XmlReader 개체의 유효성 검사를 통해 XmlDocument 개체를 만들어 contosoBooks.xml 파일이 XmlDocument 개체로 로드되면 해당 파일의 유효성을 검사합니다. 스키마 유효성 검사 오류 또는 경고가 생성되지 않고 로드되었으므로 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("https://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", "https://www.contoso.com/books")
navigator.MoveToChild("book", "https://www.contoso.com/books")
navigator.MoveToChild("author", "https://www.contoso.com/books")
navigator.AppendChild("<title>Book Title</title>")
document.Validate(validation)
navigator.MoveToParent()
navigator.MoveToChild("price", "https://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("https://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", "https://www.contoso.com/books");
navigator.MoveToChild("book", "https://www.contoso.com/books");
navigator.MoveToChild("author", "https://www.contoso.com/books");
navigator.AppendChild("<title>Book Title</title>");
document.Validate(validation);
navigator.MoveToParent();
navigator.MoveToChild("price", "https://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 파일을 입력으로 사용합니다.
<bookstore xmlns="https://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="https://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 문서를 로드한 후 유효성 검사 오류가 발생했으며 XmlDocument 클래스의 Validate 메서드를 사용하여 오류가 발견되었습니다.
노드의 스키마 형식에 따르면 새 값이 유효하지 않기 때문에 XPathNavigator 클래스의 SetTypedValue 메서드를 사용하여 수정한 사항으로 인해 InvalidCastException이 발생했습니다.
SetTypedValue 메서드를 사용하여 값을 수정하는 방법은 XPathNavigator를 사용하여 XML 데이터 수정 항목을 참조하십시오.
읽기 전용 유효성 검사
XPathDocument 클래스는 읽기 전용 메모리 내 XML 문서 표현입니다. XPathDocument 클래스와 XmlDocument 클래스는 XPathNavigator 개체를 만들어 XML 문서를 탐색하고 편집합니다. XPathDocument 클래스는 읽기 전용 클래스이므로 XPathDocument 개체에서 반환된 XPathNavigator 개체는 XPathDocument 개체에 포함된 XML 문서를 편집할 수 없습니다.
유효성 검사의 경우 이 항목의 앞부분에서 설명한 대로 유효성을 검사하는 XmlReader 개체를 사용하여 XmlDocument 개체를 만든 것과 같이 XPathDocument 개체를 만들 수 있습니다. XPathDocument 개체는 XML 문서를 로드할 때 이 문서의 유효성을 검사하지만 XPathDocument 개체에서 XML 데이터를 편집할 수 없으므로 XML 문서의 유효성을 다시 검사할 수 없습니다.
읽기 전용 및 편집 가능한 XPathNavigator 개체에 대한 자세한 내용은 XPathDocument 및 XmlDocument를 사용하여 XML 데이터 읽기 항목을 참조하십시오.
참고 항목
개념
XPathDocument 및 XmlDocument를 사용하여 XML 데이터 읽기
XPathNavigator를 사용하여 XML 데이터 선택, 평가 및 일치시키기
XPathNavigator를 사용하여 XML 데이터 액세스
XPathNavigator를 사용하여 XML 데이터 편집