Validação de esquema usando XPathNavigator
Se você usar a classe XmlDocument, poderá validar o conteúdo XML contido em um objeto XmlDocument de duas maneiras. A primeira maneira é validar o conteúdo XML usando um objeto XmlReader de validação, e a segunda maneira é usar o método Validate da classe XmlDocument. Você também pode executar a validação somente leitura do conteúdo XML usando a classe XPathDocument.
Validando dados XML
A classe XmlDocument não valida um documento XML usando validação de esquema DTD nem XSD (linguagem de definição de esquema XML) por padrão. Ela só verifica se o documento XML está bem-formado.
A primeira maneira de validar um documento XML é validar o documento enquanto ele é carregado para um objeto XmlDocument usando um objeto XmlReader de validação. A segunda maneira é validar um documento XML anteriormente não tipado usando o método Validate da classe XmlDocument. Nos dois casos, as alterações no documento XML validado podem ser revalidadas usando o método Validate da classe XmlDocument.
Validando um documento enquanto ele é carregado
Um objeto XmlReader de validação é criado passando um objeto XmlReaderSettings para o método Create da classe XmlReader que usa um objeto XmlReaderSettings como parâmetro. O objeto XmlReaderSettings passado como parâmetro tem uma propriedade ValidationType definida como Schema
e um esquema XML para o documento XML contido no objeto XmlDocument adicionado à sua propriedade Schemas. O objeto XmlReader de validação é usado para criar o objeto XmlDocument.
O exemplo a seguir valida o arquivo contosoBooks.xml
enquanto ele é carregado para o objeto XmlDocument criando o objeto XmlDocument que usa um objeto XmlReader de validação. Como o documento XML é válido de acordo com o esquema, nenhum erro ou aviso de validação de esquema é gerado.
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;
}
}
}
O exemplo usa o arquivo contosoBooks.xml
como entrada.
<?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>
O exemplo também usa contosoBooks.xsd
como entrada.
<?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>
No exemplo acima, uma XmlSchemaValidationException será gerado quando Load for chamado se nenhum tipo de atributo ou de elemento corresponder ao tipo correspondente especificado no esquema de validação. Se um ValidationEventHandler não for definido no objeto XmlReader de validação, ValidationEventHandler será chamado sempre que um tipo inválido for localizado.
Uma XmlSchemaException será gerada quando um atributo ou um elemento com TypedValue definido como invalid
for acessado pela classe XPathNavigator.
A propriedade Validity pode ser usada para determinar se um atributo ou um elemento individual é válido para acessar atributos ou elementos com a classe XPathNavigator.
Observação
Quando um documento XML é carregado para um objeto XmlDocument com um esquema associado que define os valores padrão, o objeto XmlDocument trata esses padrões como se eles tivessem aparecido no documento XML. Isso significa que a propriedade IsEmptyElement sempre retorna false
para um elemento do esquema que é usado como padrão, mesmo se o documento XML tiver sido criado como um elemento vazio.
Validando um documento com o método Validate
O método Validate da classe XmlDocument valida o documento XML contido em um objeto XmlDocument em relação aos esquemas especificados na propriedade XmlDocument do objeto Schemas e executa o aumento do conjunto de informações. O resultado é um documento XML anteriormente não tipado no objeto XmlDocument substituído por um documento tipado.
O objeto XmlDocument relata erros e avisos de validação do esquema de relatórios que usa o delegado ValidationEventHandler passado como parâmetro para o método Validate.
O exemplo a seguir valida o arquivo contosoBooks.xml
contido no objeto XmlDocument em relação ao esquema contosoBooks.xsd
contido na propriedade XmlDocument do objeto 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;
}
}
}
O exemplo usa o arquivo contosoBooks.xml
como entrada.
<?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>
O exemplo também usa contosoBooks.xsd
como entrada.
<?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>
Validando modificações
Depois que as alterações são feitas em um documento XML, você pode validar as modificações em relação ao esquema do documento XML usando o método Validate da classe XmlDocument.
O exemplo a seguir valida o arquivo contosoBooks.xml
enquanto ele é carregado para o objeto XmlDocument criando o objeto XmlDocument que usa um objeto XmlReader de validação. O documento XML é validado com êxito enquanto é carregado sem gerar erros nem avisos de validação de esquema. Em seguida, o exemplo faz duas modificações no documento XML que são inválidas de acordo com o esquema contosoBooks.xsd
. A primeira modificação insere um elemento filho inválido que resulta em um erro de validação de esquema, e a segunda modificação define o valor de um nó tipado como um valor inválido de acordo com o tipo de nó que resulta em uma exceção.
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;
}
}
}
O exemplo usa o arquivo contosoBooks.xml
como entrada.
<?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>
O exemplo também usa contosoBooks.xsd
como entrada.
<?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>
No exemplo anterior, duas modificações são feitas no documento XML contido no objeto XmlDocument. Enquanto o documento XML era carregado, todos os erros de validação de esquema encontrados teriam sido tratados pelo método de manipulador de eventos de validação e gravados no console.
Neste exemplo, os erros de validação foram introduzidos após o documento XML ser carregado e foram encontrados usando o método Validate da classe XmlDocument.
As modificações feitas usando o método SetTypedValue da classe XPathNavigator resultaram em uma InvalidCastException porque o novo valor era inválido de acordo com o tipo do nó de esquema.
Para saber mais sobre como modificar os valores usando o método SetTypedValue, confira o tópico Modificar dados XML usando XPathNavigator.
Validação somente leitura
A classe XPathDocument é uma representação somente leitura na memória de um documento XML. As classes XPathDocument e XmlDocument criam objetos XPathNavigator para navegar em documentos XML e editá-los. Como a classe XPathDocument é uma classe somente leitura, o objeto XPathNavigator retornado de objetos XPathDocument não pode editar o documento XML contido no objeto XPathDocument.
No caso de validação, você pode criar um objeto XPathDocument da mesma forma como cria um objeto XmlDocument usando um objeto XmlReader de validação, como descrito anteriormente neste tópico. O objeto XPathDocument valida o documento XML enquanto ele é carregado, mas, como não é possível editar os dados XML no objeto XPathDocument, você não pode revalidar o documento XML.
Para saber mais sobre objetos XPathNavigator editáveis e somente leitura, confira o tópico Leitura de dados XML usando XPathDocument e XmlDocument.
Confira também
- XmlDocument
- XPathDocument
- XPathNavigator
- Processar dados XML usando o modelo de dados XPath
- Lendo dados XML usando XPathDocument e XmlDocument
- Selecionando, avaliando e correspondente de dados XML usando XPathNavigator
- Acessando dados XML usando XPathNavigator
- Editando dados XML usando XPathNavigator