DOM에서의 XML 문서 유효성 검사
기본적으로 XmlDocument 클래스는 DOM(문서 개체 모델)에서 XSD(XML 스키마 정의 언어) 스키마 또는 DTD(문서 종류 정의)에 대해 XML의 유효성을 검사하지 않으며 XML이 잘 구성되었는지만 확인합니다.
DOM에서 XML의 유효성을 검사하려면 스키마의 유효성을 검사하는 XmlReader를 Load 클래스의 XmlDocument 메서드에 전달하여 DOM에 XML을 로드할 때 유효성을 검사하거나 Validate 클래스의 XmlDocument 메서드를 사용하여 DOM에서 이전에 유효성을 검사하지 않은 XML 문서의 유효성을 검사합니다.
XML 문서를 DOM에 로드할 때 유효성 검사
유효성을 검사하는 XmlDocument가 XmlReader 클래스의 Load 메서드에 전달되면 XmlDocument 클래스는 XML 데이터를 DOM에 로드할 때 유효성을 검사합니다.
유효성 검사를 수행한 후에는 스키마 기본값이 적용되고 필요한 경우 텍스트 값이 atomic 값으로 변환되며 형식 정보는 유효성이 검사된 정보 항목과 연결됩니다. 그 결과, 형식화된 XML 데이터가 이전에 형식화되지 않은 XML 데이터를 대체합니다.
XML 스키마의 유효성을 검사하는 XmlReader 만들기
XML 스키마의 유효성을 검사하는 XmlReader를 만들려면 다음 단계를 수행합니다.
새 XmlReaderSettings 인스턴스를 생성합니다.
XML 스키마를 Schemas 인스턴스의 XmlReaderSettings 속성에 추가합니다.
Schema
를 ValidationType으로 지정합니다.필요에 따라 유효성 검사 중에 발생하는 스키마 유효성 검사 오류 및 경고를 처리하는 ValidationFlags 및 ValidationEventHandler를 지정할 수도 있습니다.
마지막으로 XML 문서와 함께 XmlReaderSettings 개체를 Create 클래스의 XmlReader 메서드에 전달하여 스키마의 유효성을 검사하는 XmlReader를 만듭니다.
예시
다음 코드 예제에서는 스키마의 유효성을 검사하는 XmlReader가 DOM에 로드된 XML 데이터의 유효성을 검사합니다. 또한 XML 문서를 잘못 수정하고 이 문서의 유효성을 다시 검사하므로 스키마 유효성 검사 오류가 발생합니다. 마지막으로 오류 중 하나를 수정한 다음 XML 문서의 일부에 대한 유효성을 부분적으로 검사합니다.
#using <System.Xml.dll>
using namespace System;
using namespace System::Xml;
using namespace System::Xml::Schema;
ref class XmlDocumentValidationExample
{
public:
static void Main()
{
try
{
// Create a schema validating XmlReader.
XmlReaderSettings^ settings = gcnew XmlReaderSettings();
settings->Schemas->Add("http://www.contoso.com/books", "contosoBooks.xsd");
ValidationEventHandler^ eventHandler = gcnew ValidationEventHandler(ValidationEventHandlerOne);
settings->ValidationEventHandler += eventHandler;
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 = gcnew 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 = gcnew 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: {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";
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(eventHandler);
// 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(eventHandler, bookNode);
}
catch (XmlException^ ex)
{
Console::WriteLine("XmlDocumentValidationExample.XmlException: {0}", ex->Message);
}
catch(XmlSchemaValidationException^ ex)
{
Console::WriteLine("XmlDocumentValidationExample.XmlSchemaValidationException: {0}", ex->Message);
}
catch (Exception^ ex)
{
Console::WriteLine("XmlDocumentValidationExample.Exception: {0}", ex->Message);
}
}
static void ValidationEventHandlerOne(Object^ sender, ValidationEventArgs^ args)
{
if (args->Severity == XmlSeverityType::Warning)
Console::Write("\nWARNING: ");
else if (args->Severity == XmlSeverityType::Error)
Console::Write("\nERROR: ");
Console::WriteLine(args->Message);
}
};
int main()
{
XmlDocumentValidationExample::Main();
return 0;
}
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: {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";
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: {0}", ex.Message);
}
catch(XmlSchemaValidationException ex)
{
Console.WriteLine("XmlDocumentValidationExample.XmlSchemaValidationException: {0}", ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("XmlDocumentValidationExample.Exception: {0}", 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>
XML 데이터를 DOM에 로드할 때 유효성을 검사하는 경우 다음을 고려해야 합니다.
위 예제에서 잘못된 형식이 발견될 때마다 ValidationEventHandler가 호출됩니다. ValidationEventHandler가 유효성을 검사하는 XmlReader에 대해 설정되어 있지 않으면 특성 또는 요소 형식이 유효성 검사 스키마에 지정된 해당 형식과 일치하지 않은 경우 XmlSchemaValidationException가 호출될 때 Load이 throw됩니다.
기본값을 정의하는 스키마가 연결되어 있는 XML 문서를 XmlDocument 개체에 로드하면 XmlDocument는 이 기본값이 XML 문서에 나타난 것처럼 처리합니다. 그러므로 IsEmptyElement 속성은 항상 스키마의 기본값으로 설정된 요소에 대해
false
를 반환합니다. XML 문서에서도 빈 요소로 작성됩니다.
DOM에서의 XML 문서 유효성 검사
Validate 클래스의 XmlDocument 메서드는 XmlDocument 개체의 Schemas 속성에 있는 스키마에 대해 DOM에 로드된 XML 데이터의 유효성을 검사합니다. 유효성 검사를 수행한 후에는 스키마 기본값이 적용되고 필요한 경우 텍스트 값이 atomic 값으로 변환되며 형식 정보는 유효성이 검사된 정보 항목과 연결됩니다. 그 결과, 형식화된 XML 데이터가 이전에 형식화되지 않은 XML 데이터를 대체합니다.
아래 예제는 위의 "XML 문서를 DOM에 로드할 때 유효성 검사"의 예제와 비슷합니다. 이 예제에서는 XML 문서를 DOM에 로드할 때 유효성을 검사하지 않고 DOM에 로드한 후 Validate 클래스의 XmlDocument 메서드를 사용하여 검사합니다. Validate 메서드는 Schemas의 XmlDocument 속성에 포함된 XML 스키마에 대해 XML 문서의 유효성을 검사합니다. 또한 XML 문서를 잘못 수정하고 이 문서의 유효성을 다시 검사하므로 스키마 유효성 검사 오류가 발생합니다. 마지막으로 오류 중 하나를 수정한 다음 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: {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";
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: {0}", ex.Message);
}
catch(XmlSchemaValidationException ex)
{
Console.WriteLine("XmlDocumentValidationExample.XmlSchemaValidationException: {0}", ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("XmlDocumentValidationExample.Exception: {0}", 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
파일을 입력으로 사용합니다.
유효성 검사 오류 및 경고 처리
DOM에 로드된 XML 데이터의 유효성을 검사하면 XML 스키마 유효성 검사 오류가 보고됩니다. XML 데이터를 로드할 때 수행한 유효성 검사 또는 이전에 유효성을 검사하지 않은 XML 문서의 유효성 검사에서 발견된 모든 스키마 유효성 검사 오류에 대해 알림을 받습니다.
유효성 검사 오류는 ValidationEventHandler에서 처리합니다. ValidationEventHandler를 XmlReaderSettings 인스턴스에 지정하거나 Validate 클래스의 XmlDocument 메서드에 전달한 경우 ValidationEventHandler는 스키마 유효성 검사 오류를 처리하며 그렇지 않은 경우에는 스키마 유효성 검사 오류가 발생할 때 XmlSchemaValidationException이 일어납니다.
참고 항목
ValidationEventHandler에 의해 예외가 발생하여 프로세스가 중지되지 않은 경우에는 스키마 유효성 검사 오류가 발생해도 XML 데이터가 DOM에 로드됩니다.
ReportValidationWarnings 플래그를 XmlReaderSettings 개체에 지정하지 않으면 스키마 유효성 검사 경고가 보고되지 않습니다.
ValidationEventHandler를 설명하는 예제는 위의 "XML 문서를 DOM에 로드할 때 유효성 검사" 및 "DOM에서의 XML 문서 유효성 검사"를 참조하세요.
참고 항목
.NET