Validação de esquema usando XPathNavigator
Usando a XmlDocument classe, você pode validar o conteúdo XML contido em um XmlDocument objeto de duas maneiras. A primeira maneira é validar o conteúdo XML usando um objeto de XmlReader validação e a segunda maneira é usar o ValidateXmlDocument método da classe. Você também pode executar a validação somente leitura do conteúdo XML usando a XPathDocument classe.
Validando dados XML
A XmlDocument classe não valida um documento XML usando DTD ou validação de esquema XSD (XML schema definition language) por padrão. Ele apenas verifica se o documento XML está bem formado.
A primeira maneira de validar um documento XML é validar o documento à medida que ele é carregado em um XmlDocument objeto usando um objeto de validação XmlReader . A segunda maneira é validar um documento XML não tipado anteriormente usando o Validate método da XmlDocument classe. Em ambos os casos, as alterações no documento XML validado podem ser revalidadas usando o ValidateXmlDocument método da classe.
Validando um documento à medida que ele é carregado
Um objeto de XmlReader validação é criado passando um XmlReaderSettings objeto para o Create método da XmlReader classe que usa um XmlReaderSettings objeto como parâmetro. O XmlReaderSettings objeto passado como um parâmetro tem uma ValidationType propriedade definida como Schema
e um esquema XML para o documento XML contido no XmlDocument objeto adicionado à sua Schemas propriedade. O objeto de XmlReader validação é então usado para criar o XmlDocument objeto.
O exemplo a seguir valida o contosoBooks.xml
arquivo à medida que ele é carregado no objeto, XmlDocument criando o XmlDocument objeto usando um objeto de validação XmlReader . Como o documento XML é válido de acordo com seu 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 contosoBooks.xml
arquivo como uma 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 toma o contosoBooks.xsd
como uma 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, um XmlSchemaValidationException será lançado quando Load for chamado se qualquer atributo ou tipo de elemento não corresponder ao tipo correspondente especificado no esquema de validação. Se a ValidationEventHandler estiver definido na validação XmlReader, o ValidationEventHandler será chamado sempre que um tipo inválido for encontrado.
Um XmlSchemaException será lançado quando um atributo ou elemento com TypedValue definido como invalid
for acessado XPathNavigatorpelo .
A Validity propriedade pode ser usada para determinar se um atributo ou elemento individual é válido ou não ao acessar atributos ou elementos com o XPathNavigator.
Nota
Quando um documento XML é carregado em um XmlDocument objeto com um esquema associado que define valores padrão, o XmlDocument objeto trata esses padrões como se aparecessem no documento XML. Isso significa que a IsEmptyElement propriedade sempre retorna false
para um elemento que foi padronizado do esquema, mesmo que no documento XML ele tenha sido escrito como um elemento vazio.
Validando um documento usando o método Validate
O Validate método da classe valida XmlDocument o documento XML contido em um XmlDocument objeto em relação aos esquemas especificados Schemas na propriedade do objeto e executa o XmlDocument aumento do infoset. O resultado é um documento XML não tipado XmlDocument anteriormente no objeto substituído por um documento digitado.
O XmlDocument objeto relata erros de validação de esquema e avisos usando o ValidationEventHandler delegado passado como parâmetro para o Validate método.
O exemplo a seguir valida o contosoBooks.xml
arquivo contido no objeto em relação ao contosoBooks.xsd
XmlDocument esquema contido na XmlDocument propriedade do Schemas objeto.
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 contosoBooks.xml
arquivo como uma 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 toma o contosoBooks.xsd
como uma 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>
Validação de modificações
Depois que as modificações são feitas em um documento XML, você pode validar as modificações em relação ao esquema para o documento XML usando o ValidateXmlDocument método da classe.
O exemplo a seguir valida o contosoBooks.xml
arquivo à medida que ele é carregado no objeto, XmlDocument criando o XmlDocument objeto usando um objeto de validação XmlReader . O documento XML é validado com êxito à medida que é carregado sem gerar erros ou 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 contosoBooks.xsd
esquema. A primeira modificação insere um elemento filho inválido, resultando em um erro de validação de esquema, e a segunda modificação define o valor de um nó digitado como um valor que é inválido de acordo com o tipo do nó, resultando 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 contosoBooks.xml
arquivo como uma 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 toma o contosoBooks.xsd
como uma 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, duas modificações são feitas no documento XML contido no XmlDocument objeto. À medida que o documento XML era carregado, quaisquer erros de validação de esquema encontrados teriam sido tratados pelo método manipulador de eventos de validação e gravados no console.
Neste exemplo, os erros de validação foram introduzidos depois que o documento XML foi carregado e foram encontrados usando o ValidateXmlDocument método da classe.
As modificações feitas usando o SetTypedValueXPathNavigator método da classe resultaram em um InvalidCastException porque o novo valor era inválido de acordo com o tipo de esquema do nó.
Para obter mais informações sobre como modificar valores usando o SetTypedValue método, consulte o tópico Modificar dados XML usando XPathNavigator .
Validação somente leitura
A XPathDocument classe é uma representação somente leitura na memória de um documento XML. Tanto a XPathDocument classe quanto a XmlDocument classe criam XPathNavigator objetos para navegar e editar documentos XML. Como a XPathDocument classe é uma classe somente leitura, XPathNavigator os objetos retornados de XPathDocument objetos não podem editar o documento XML contido no XPathDocument objeto.
No caso da validação, você pode criar um XPathDocument objeto da mesma forma que cria um XmlDocument objeto usando um objeto de validação XmlReader , conforme descrito anteriormente neste tópico. O XPathDocument objeto valida o documento XML à medida que é carregado, mas como não é possível editar os XPathDocument dados XML no objeto, não é possível revalidar o documento XML.
Para obter mais informações sobre objetos somente leitura e editáveis XPathNavigator , consulte o tópico Lendo dados XML usando XPathDocument e XmlDocument .