Partilhar via


XmlSchemaValidator Validação baseada em push

A classe XmlSchemaValidator fornece um mecanismo eficiente e de alto desempenho para validar dados XML em relação a esquemas XML de maneira baseada em push. Por exemplo, a classe XmlSchemaValidator permite validar diretamente um infoset XML sem ter que serializá-lo como um documento XML e, em seguida, reanalisar o documento utilizando um leitor XML validador.

A classe XmlSchemaValidator pode ser usada em cenários avançados, como a criação de mecanismos de validação sobre fontes de dados XML personalizadas ou como uma maneira de criar um gravador XML de validação.

A seguir está um exemplo de uso da classe XmlSchemaValidator para validar o arquivo contosoBooks.xml em relação ao esquema contosoBooks.xsd. O exemplo usa a classe XmlSerializer para desserializar o arquivo contosoBooks.xml e passar o valor dos nós para os métodos da classe XmlSchemaValidator.

Observação

Este exemplo é usado ao longo das seções deste tópico.

using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using System.Collections;

namespace Microsoft.Samples.Xml.Schema
{
    class XmlSchemaValidatorExamples
    {
        static void Main()
        {
            // The XML document to deserialize into the XmlSerializer object.
            XmlReader reader = XmlReader.Create("contosoBooks.xml");

            // The XmlSerializer object.
            XmlSerializer serializer = new XmlSerializer(typeof(ContosoBooks));
            ContosoBooks books = (ContosoBooks)serializer.Deserialize(reader);

            // The XmlSchemaSet object containing the schema used to validate the XML document.
            XmlSchemaSet schemaSet = new XmlSchemaSet();
            schemaSet.Add("http://www.contoso.com/books", "contosoBooks.xsd");

            // The XmlNamespaceManager object used to handle namespaces.
            XmlNamespaceManager manager = new XmlNamespaceManager(reader.NameTable);

            // Assign a ValidationEventHandler to handle schema validation warnings and errors.
            XmlSchemaValidator validator = new XmlSchemaValidator(reader.NameTable, schemaSet, manager, XmlSchemaValidationFlags.None);
            validator.ValidationEventHandler += new ValidationEventHandler(SchemaValidationEventHandler);

            // Initialize the XmlSchemaValidator object.
            validator.Initialize();

            // Validate the bookstore element, verify that all required attributes are present
            // and prepare to validate child content.
            validator.ValidateElement("bookstore", "http://www.contoso.com/books", null);
            validator.GetUnspecifiedDefaultAttributes(new ArrayList());
            validator.ValidateEndOfAttributes(null);

            // Get the next expected element in the bookstore context.
            XmlSchemaParticle[] particles = validator.GetExpectedParticles();
            XmlSchemaElement nextElement = particles[0] as XmlSchemaElement;
            Console.WriteLine($"Expected Element: '{nextElement.Name}'");

            foreach (BookType book in books.Book)
            {
                // Validate the book element.
                validator.ValidateElement("book", "http://www.contoso.com/books", null);

                // Get the expected attributes for the book element.
                Console.Write("\nExpected attributes: ");
                XmlSchemaAttribute[] attributes = validator.GetExpectedAttributes();
                foreach (XmlSchemaAttribute attribute in attributes)
                {
                    Console.Write("'{0}' ", attribute.Name);
                }
                Console.WriteLine();

                // Validate the genre attribute and display its post schema validation information.
                if (book.Genre != null)
                {
                    validator.ValidateAttribute("genre", "", book.Genre, schemaInfo);
                }
                DisplaySchemaInfo();

                // Validate the publicationdate attribute and display its post schema validation information.
                if (book.PublicationDate != null)
                {
                    validator.ValidateAttribute("publicationdate", "", dateTimeGetter(book.PublicationDate), schemaInfo);
                }
                DisplaySchemaInfo();

                // Validate the ISBN attribute and display its post schema validation information.
                if (book.Isbn != null)
                {
                    validator.ValidateAttribute("ISBN", "", book.Isbn, schemaInfo);
                }
                DisplaySchemaInfo();

                // After validating all the attributes for the current element with ValidateAttribute method,
                // you must call GetUnspecifiedDefaultAttributes to validate the default attributes.
                validator.GetUnspecifiedDefaultAttributes(new ArrayList());

                // Verify that all required attributes of the book element are present
                // and prepare to validate child content.
                validator.ValidateEndOfAttributes(null);

                // Validate the title element and its content.
                validator.ValidateElement("title", "http://www.contoso.com/books", null);
                validator.ValidateEndElement(null, book.Title);

                // Validate the author element, verify that all required attributes are present
                // and prepare to validate child content.
                validator.ValidateElement("author", "http://www.contoso.com/books", null);
                validator.GetUnspecifiedDefaultAttributes(new ArrayList());
                validator.ValidateEndOfAttributes(null);

                if (book.Author.Name != null)
                {
                    // Validate the name element and its content.
                    validator.ValidateElement("name", "http://www.contoso.com/books", null);
                    validator.ValidateEndElement(null, book.Author.Name);
                }

                if (book.Author.FirstName != null)
                {
                    // Validate the first-name element and its content.
                    validator.ValidateElement("first-name", "http://www.contoso.com/books", null);
                    validator.ValidateEndElement(null, book.Author.FirstName);
                }

                if (book.Author.LastName != null)
                {
                    // Validate the last-name element and its content.
                    validator.ValidateElement("last-name", "http://www.contoso.com/books", null);
                    validator.ValidateEndElement(null, book.Author.LastName);
                }

                // Validate the content of the author element.
                validator.ValidateEndElement(null);

                // Validate the price element and its content.
                validator.ValidateElement("price", "http://www.contoso.com/books", null);
                validator.ValidateEndElement(null, book.Price);

                // Validate the content of the book element.
                validator.ValidateEndElement(null);
            }

            // Validate the content of the bookstore element.
            validator.ValidateEndElement(null);

            // Close the XmlReader object.
            reader.Close();
        }

        static XmlSchemaInfo schemaInfo = new XmlSchemaInfo();
        static object dateTimeGetterContent;

        static object dateTimeGetterHandle()
        {
            return dateTimeGetterContent;
        }

        static XmlValueGetter dateTimeGetter(DateTime dateTime)
        {
            dateTimeGetterContent = dateTime;
            return new XmlValueGetter(dateTimeGetterHandle);
        }

        static void DisplaySchemaInfo()
        {
            if (schemaInfo.SchemaElement != null)
            {
                Console.WriteLine($"Element '{schemaInfo.SchemaElement.Name}' with type '{schemaInfo.SchemaType}' is '{schemaInfo.Validity}'");
            }
            else if (schemaInfo.SchemaAttribute != null)
            {
                Console.WriteLine($"Attribute '{schemaInfo.SchemaAttribute.Name}' with type '{schemaInfo.SchemaType}' is '{schemaInfo.Validity}'");
            }
        }

        static void SchemaValidationEventHandler(object sender, ValidationEventArgs e)
        {
            switch (e.Severity)
            {
                case XmlSeverityType.Error:
                    Console.WriteLine($"\nError: {e.Message}");
                    break;
                case XmlSeverityType.Warning:
                    Console.WriteLine($"\nWarning: {e.Message}");
                    break;
            }
        }
    }

    [XmlRootAttribute("bookstore", Namespace = "http://www.contoso.com/books", IsNullable = false)]
    public class ContosoBooks
    {
        [XmlElementAttribute("book")]
        public BookType[] Book;
    }

    public class BookType
    {
        [XmlAttributeAttribute("genre")]
        public string Genre;

        [XmlAttributeAttribute("publicationdate", DataType = "date")]
        public DateTime PublicationDate;

        [XmlAttributeAttribute("ISBN")]
        public string Isbn;

        [XmlElementAttribute("title")]
        public string Title;

        [XmlElementAttribute("author")]
        public BookAuthor Author;

        [XmlElementAttribute("price")]
        public Decimal Price;
    }

    public class BookAuthor
    {
        [XmlElementAttribute("name")]
        public string Name;

        [XmlElementAttribute("first-name")]
        public string FirstName;

        [XmlElementAttribute("last-name")]
        public string LastName;
    }
}
Imports System.Xml
Imports System.Xml.Schema
Imports System.Xml.Serialization
Imports System.Collections


Namespace Microsoft.Samples.Xml.Schema

    Class XmlSchemaValidatorExamples

        Shared Sub Main()

            ' The XML document to deserialize into the XmlSerializer object.
            Dim reader As XmlReader = XmlReader.Create("contosoBooks.xml")

            ' The XmlSerializer object.
            Dim serializer As XmlSerializer = New XmlSerializer(GetType(ContosoBooks))
            Dim books As ContosoBooks = CType(serializer.Deserialize(reader), ContosoBooks)

            ' The XmlSchemaSet object containing the schema used to validate the XML document.
            Dim schemaSet As XmlSchemaSet = New XmlSchemaSet()
            schemaSet.Add("http://www.contoso.com/books", "contosoBooks.xsd")

            ' The XmlNamespaceManager object used to handle namespaces.
            Dim manager As XmlNamespaceManager = New XmlNamespaceManager(reader.NameTable)

            ' Assign a ValidationEventHandler to handle schema validation warnings and errors.
            Dim validator As XmlSchemaValidator = New XmlSchemaValidator(reader.NameTable, schemaSet, manager, XmlSchemaValidationFlags.None)
            'validator.ValidationEventHandler += New ValidationEventHandler(SchemaValidationEventHandler)
            AddHandler validator.ValidationEventHandler, AddressOf SchemaValidationEventHandler

            ' Initialize the XmlSchemaValidator object.
            validator.Initialize()

            ' Validate the bookstore element, verify that all required attributes are present
            ' and prepare to validate child content.
            validator.ValidateElement("bookstore", "http://www.contoso.com/books", Nothing)

            validator.GetUnspecifiedDefaultAttributes(New ArrayList())
            validator.ValidateEndOfAttributes(Nothing)

            ' Get the next expected element in the bookstore context.
            Dim particles() As XmlSchemaParticle = validator.GetExpectedParticles()
            Dim nextElement As XmlSchemaElement = particles(0)
            Console.WriteLine("Expected Element: '{0}'", nextElement.Name)

            For Each book As BookType In books.book
                ' Validate the book element.
                validator.ValidateElement("book", "http://www.contoso.com/books", Nothing)

                ' Get the expected attributes for the book element.
                Console.Write(vbCrLf & "Expected attributes: ")
                Dim attributes() As XmlSchemaAttribute = validator.GetExpectedAttributes()
                For Each attribute As XmlSchemaAttribute In attributes
                    Console.Write("'{0}' ", attribute.Name)
                Next
                Console.WriteLine()

                ' Validate the genre attribute and display its post schema validation information.
                If Not book.Genre Is Nothing Then
                    validator.ValidateAttribute("genre", "", book.Genre, schemaInfo)
                End If
                DisplaySchemaInfo()

                ' Validate the publicationdate attribute and display its post schema validation information.
                If Not book.PublicationDate = Nothing Then
                    validator.ValidateAttribute("publicationdate", "", dateTimeGetter(book.PublicationDate), schemaInfo)
                End If
                DisplaySchemaInfo()

                ' Validate the ISBN attribute and display its post schema validation information.
                If Not book.Isbn Is Nothing Then
                    validator.ValidateAttribute("ISBN", "", book.Isbn, schemaInfo)
                End If
                DisplaySchemaInfo()

                ' After validating all the attributes for the current element with ValidateAttribute method,
                ' you must call GetUnspecifiedDefaultAttributes to validate the default attributes.
                validator.GetUnspecifiedDefaultAttributes(New ArrayList())

                ' Verify that all required attributes of the book element are present
                ' and prepare to validate child content.
                validator.ValidateEndOfAttributes(Nothing)

                ' Validate the title element and its content.
                validator.ValidateElement("title", "http://www.contoso.com/books", Nothing)
                validator.ValidateEndElement(Nothing, book.Title)

                ' Validate the author element, verify that all required attributes are present
                ' and prepare to validate child content.
                validator.ValidateElement("author", "http://www.contoso.com/books", Nothing)

                validator.GetUnspecifiedDefaultAttributes(New ArrayList())
                validator.ValidateEndOfAttributes(Nothing)

                If Not book.Author.Name Is Nothing Then
                    ' Validate the name element and its content.
                    validator.ValidateElement("name", "http://www.contoso.com/books", Nothing)
                    validator.ValidateEndElement(Nothing, book.Author.Name)
                End If

                If Not book.Author.FirstName Is Nothing Then
                    ' Validate the first-name element and its content.
                    validator.ValidateElement("first-name", "http://www.contoso.com/books", Nothing)
                    validator.ValidateEndElement(Nothing, book.Author.FirstName)

                End If

                If Not book.Author.LastName Is Nothing Then
                    ' Validate the last-name element and its content.
                    validator.ValidateElement("last-name", "http://www.contoso.com/books", Nothing)
                    validator.ValidateEndElement(Nothing, book.Author.LastName)
                End If

                ' Validate the content of the author element.
                validator.ValidateEndElement(Nothing)

                ' Validate the price element and its content.
                validator.ValidateElement("price", "http://www.contoso.com/books", Nothing)
                validator.ValidateEndElement(Nothing, book.Price)

                ' Validate the content of the book element.
                validator.ValidateEndElement(Nothing)
            Next

            ' Validate the content of the bookstore element.
            validator.ValidateEndElement(Nothing)

            ' Close the XmlReader object.
            reader.Close()

        End Sub

        Shared schemaInfo As XmlSchemaInfo = New XmlSchemaInfo()
        Shared dateTimeGetterContent As Object

        Shared Function dateTimeGetterHandle() As Object

            Return dateTimeGetterContent

        End Function

        Shared Function dateTimeGetter(ByVal dateTime As DateTime) As XmlValueGetter

            dateTimeGetterContent = dateTime
            Return New XmlValueGetter(AddressOf dateTimeGetterHandle)

        End Function

        Shared Sub DisplaySchemaInfo()

            If Not schemaInfo.SchemaElement Is Nothing Then
                Console.WriteLine("Element '{0}' with type '{1}' is '{2}'", schemaInfo.SchemaElement.Name, schemaInfo.SchemaType, schemaInfo.Validity)
            ElseIf Not schemaInfo.SchemaAttribute Is Nothing Then
                Console.WriteLine("Attribute '{0}' with type '{1}' is '{2}'", schemaInfo.SchemaAttribute.Name, schemaInfo.SchemaType, schemaInfo.Validity)
            End If

        End Sub

        Shared Sub SchemaValidationEventHandler(ByVal sender As Object, ByVal e As ValidationEventArgs)

            Select Case e.Severity
                Case XmlSeverityType.Error
                    Console.WriteLine(vbCrLf & "Error: {0}", e.Message)
                    Exit Sub
                Case XmlSeverityType.Warning
                    Console.WriteLine(vbCrLf & "Warning: {0}", e.Message)
                    Exit Sub
            End Select

        End Sub

    End Class

    <XmlRootAttribute("bookstore", Namespace:="http://www.contoso.com/books", IsNullable:=False)> _
    Public Class ContosoBooks

        <XmlElementAttribute("book")> _
        Public book() As BookType

    End Class

    Public Class BookType

        <XmlAttributeAttribute("genre")> _
        Public Genre As String

        <XmlAttributeAttribute("publicationdate", DataType:="date")> _
        Public PublicationDate As DateTime

        <XmlAttributeAttribute("ISBN")> _
        Public Isbn As String

        <XmlElementAttribute("title")> _
        Public Title As String

        <XmlElementAttribute("author")> _
        Public Author As BookAuthor

        <XmlElementAttribute("price")> _
        Public Price As Decimal

    End Class

    Public Class BookAuthor

        <XmlElementAttribute("name")> _
        Public Name As String

        <XmlElementAttribute("first-name")> _
        Public FirstName As String

        <XmlElementAttribute("last-name")> _
        Public LastName As String

    End Class

End Namespace

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 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>

Validando dados XML usando XmlSchemaValidator

Para começar a validar um infoset XML, você deve primeiro inicializar uma nova instância da classe XmlSchemaValidator usando o construtor XmlSchemaValidator.

O construtor XmlSchemaValidator usa objetos XmlNameTable, XmlSchemaSete XmlNamespaceManager como parâmetros, bem como um valor XmlSchemaValidationFlags como parâmetro. O objeto XmlNameTable é usado para atomizar cadeias de caracteres de namespace bem conhecidas, como o namespace do esquema, o namespace XML e assim por diante, e é passado para o método ParseValue durante a validação de conteúdo simples. O objeto XmlSchemaSet contém os esquemas XML usados para validar o infoset XML. O objeto XmlNamespaceManager é usado para resolver namespaces encontrados durante a validação. O valor XmlSchemaValidationFlags é usado para desativar determinados recursos de validação.

Para obter mais informações sobre o construtor XmlSchemaValidator, consulte a documentação de referência da classe XmlSchemaValidator.

Inicializando a validação

Depois que um objeto XmlSchemaValidator foi construído, há dois métodos de Initialize sobrecarregados usados para inicializar o estado do objeto XmlSchemaValidator. A seguir estão os dois métodos Initialize.

O método XmlSchemaValidator.Initialize padrão inicializa um objeto XmlSchemaValidator em seu estado inicial, e o método XmlSchemaValidator.Initialize sobrecarregado que toma um XmlSchemaObject como parâmetro inicializa um objeto XmlSchemaValidator em seu estado inicial para validação parcial.

Ambos os métodos Initialize só podem ser chamados imediatamente após um objeto XmlSchemaValidator ter sido construído ou após uma chamada para EndValidation.

Para obter um exemplo do método XmlSchemaValidator.Initialize, veja o exemplo na introdução. Para obter mais informações sobre o método Initialize, consulte a documentação de referência de classe XmlSchemaValidator.

Validação parcial

O método XmlSchemaValidator.Initialize que usa um XmlSchemaObject como parâmetro inicializa um objeto XmlSchemaValidator em seu estado inicial para validação parcial.

No exemplo a seguir, um XmlSchemaObject é inicializado para validação parcial usando o método XmlSchemaValidator.Initialize. Para passar o elemento de esquema orderNumber, selecione o elemento de esquema por XmlQualifiedName na coleção XmlSchemaObjectTable, a qual é retornada pela propriedade GlobalElements do objeto XmlSchemaSet. Em seguida, o objeto XmlSchemaValidator valida esse elemento específico.

Dim schemaSet As XmlSchemaSet = New XmlSchemaSet()
schemaSet.Add(Nothing, "schema.xsd")
schemaSet.Compile()
Dim nameTable As NameTable = New NameTable()
Dim manager As XmlNamespaceManager = New XmlNamespaceManager(nameTable)

Dim validator As XmlSchemaValidator = New XmlSchemaValidator(nameTable, schemaSet, manager, XmlSchemaValidationFlags.None)
validator.Initialize(schemaSet.GlobalElements.Item(New XmlQualifiedName("orderNumber")))

validator.ValidateElement("orderNumber", "", Nothing)
validator.ValidateEndOfAttributes(Nothing)
validator.ValidateText("123")
validator.ValidateEndElement(Nothing)
XmlSchemaSet schemaSet = new XmlSchemaSet();
schemaSet.Add(null, "schema.xsd");
schemaSet.Compile();
NameTable nameTable = new NameTable();
XmlNamespaceManager manager = new XmlNamespaceManager(nameTable);

XmlSchemaValidator validator = new XmlSchemaValidator(nameTable, schemaSet, manager, XmlSchemaValidationFlags.None);
validator.Initialize(schemaSet.GlobalElements[new XmlQualifiedName("orderNumber")]);

validator.ValidateElement("orderNumber", "", null);
validator.ValidateEndOfAttributes(null);
validator.ValidateText("123");
validator.ValidateEndElement(null);

O exemplo usa o seguinte esquema XML como entrada.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="orderNumber" type="xs:int" />
</xs:schema>

Para obter mais informações sobre o método Initialize, consulte a documentação de referência de classe XmlSchemaValidator.

Adicionando esquemas adicionais

O método AddSchema da classe XmlSchemaValidator é usado para adicionar um esquema XML ao conjunto de esquemas usados durante a validação. O método AddSchema pode ser usado para simular o efeito de encontrar um esquema XML embutido no infoset XML que está sendo validado.

Observação

O namespace de destino do parâmetro XmlSchema não pode corresponder ao de qualquer elemento ou atributo já encontrado pelo objeto XmlSchemaValidator.

Se o valor XmlSchemaValidationFlags.ProcessInlineSchema não foi passado como um parâmetro para o construtor XmlSchemaValidator, o método AddSchema não faz nada.

O resultado do método AddSchema depende do contexto atual do nó XML que está sendo validado. Para obter mais informações sobre contextos de validação, consulte a seção "Contexto de validação" deste tópico.

Para obter mais informações sobre o método AddSchema, consulte a documentação de referência de classe XmlSchemaValidator.

Validando elementos, atributos e conteúdo

A classe XmlSchemaValidator fornece vários métodos usados para validar elementos, atributos e conteúdo em um infoset XML em relação a esquemas XML. A tabela a seguir descreve cada um desses métodos.

Método Descrição
ValidateElement Valida o nome do elemento no contexto atual.
ValidateAttribute Valida o atributo no contexto do elemento atual ou em relação ao objeto XmlSchemaAttribute passado como um parâmetro para o método Initialize.
ValidateEndOfAttributes Verifica se todos os atributos necessários no contexto do elemento estão presentes e prepara o objeto XmlSchemaValidator para validar o conteúdo filho do elemento.
ValidateText Valida se o texto é permitido no contexto do elemento atual e acumula o texto para validação se o elemento atual tiver conteúdo simples.
ValidateWhitespace Valida se o espaço em branco é permitido no contexto do elemento atual e acumula o espaço em branco para validação se o elemento atual tem conteúdo simples.
ValidateEndElement Verifica se o conteúdo de texto do elemento é válido de acordo com seu tipo de dados para elementos com conteúdo simples e verifica se o conteúdo do elemento atual está completo para elementos com conteúdo complexo.
SkipToEndElement Ignora a validação do conteúdo do elemento atual e prepara o objeto XmlSchemaValidator para validar o conteúdo no contexto do elemento pai.
EndValidation Termina a validação e verifica as restrições de identidade para todo o documento XML se a opção de validação ProcessIdentityConstraints estiver definida.

Observação

A classe XmlSchemaValidator tem uma transição de estado definida que impõe a sequência e a ocorrência de chamadas feitas para cada um dos métodos descritos na tabela anterior. A transição de estado específica da classe XmlSchemaValidator é descrita na seção "XmlSchemaValidator State Transition" deste tópico.

Para obter um exemplo dos métodos usados para validar elementos, atributos e conteúdo em um infoset XML, consulte o exemplo na seção anterior. Para obter mais informações sobre esses métodos, consulte a documentação de referência de classe XmlSchemaValidator.

Validando conteúdo usando um XmlValueGetter

O XmlValueGetterdelegate pode ser usado para passar o valor dos nós de atributo, texto ou espaço em branco para tipos CLR (Common Language Runtime), compatíveis com o tipo XSD (XML Schema Definition Language) dos nós de atributo, texto ou espaço em branco. Um XmlValueGetterdelegate é útil se o valor CLR de um atributo, texto ou nó de espaço em branco já estiver disponível e evita o custo de convertê-lo em um string e, em seguida, analisá-lo novamente para validação.

Os métodos ValidateAttribute, ValidateTexte ValidateWhitespace têm sobrecarga e aceitam o valor dos nós de atributo, texto, ou espaço em branco como um string ou XmlValueGetterdelegate.

Os seguintes métodos da classe XmlSchemaValidator aceitam um XmlValueGetterdelegate como parâmetro.

A seguir está um exemplo XmlValueGetterdelegate retirado do exemplo de classe XmlSchemaValidator na introdução. O XmlValueGetterdelegate retorna o valor de um atributo como um objeto DateTime. Para validar esse objeto DateTime retornado pelo XmlValueGetter, o objeto XmlSchemaValidator primeiro o converte para o ValueType (ValueType é o mapeamento CLR padrão para o tipo XSD) para o tipo de dados do atributo e, em seguida, verifica facetas no valor convertido.

Shared dateTimeGetterContent As Object

Shared Function DateTimeGetterHandle() As Object
    Return dateTimeGetterContent
End Function

Shared Function DateTimeGetter(dateTime As DateTime) As XmlValueGetter
    dateTimeGetterContent = dateTime
    Return New XmlValueGetter(AddressOf DateTimeGetterHandle)
End Function
static object dateTimeGetterContent;

static object DateTimeGetterHandle()
{
    return dateTimeGetterContent;
}

static XmlValueGetter DateTimeGetter(DateTime dateTime)
{
    dateTimeGetterContent = dateTime;
    return new XmlValueGetter(dateTimeGetterHandle);
}

Para obter um exemplo completo do XmlValueGetterdelegate, veja o exemplo na introdução. Para obter mais informações sobre o XmlValueGetterdelegate, consulte a documentação de referência de classe XmlValueGettere XmlSchemaValidator.

Post-Schema -Validation-Information

A classe XmlSchemaInfo representa algumas dasValidation-Information Post-Schema de um nó XML validado pela classe XmlSchemaValidator. Vários métodos da classe XmlSchemaValidator aceitam um objeto XmlSchemaInfo como um parâmetro opcional, (null) out.

Após a validação bem-sucedida, as propriedades do objeto XmlSchemaInfo são definidas com os resultados da validação. Por exemplo, após a validação bem-sucedida de um atributo usando o método ValidateAttribute, as propriedades XmlSchemaInfo, SchemaAttribute, SchemaTypee MemberType do objeto Validity (se especificado) são definidas com os resultados da validação.

Os seguintes métodos de classe XmlSchemaValidator aceitam um objeto XmlSchemaInfo como um parâmetro out.

Para obter um exemplo completo da classe XmlSchemaInfo, consulte o exemplo na introdução. Para obter mais informações sobre a classe XmlSchemaInfo, consulte a documentação de referência de classe XmlSchemaInfo.

Recuperando partículas esperadas, atributos e atributos padrão não especificados

A classe XmlSchemaValidator fornece os métodos GetExpectedAttributes, GetExpectedParticlese GetUnspecifiedDefaultAttributes para recuperar as partículas esperadas, atributos e atributos padrão não especificados no contexto de validação atual.

Recuperando partículas esperadas

O método GetExpectedParticles retorna uma matriz de objetos XmlSchemaParticle contendo as partículas esperadas no contexto de elemento atual. As partículas válidas que podem ser retornadas pelo método GetExpectedParticles são instâncias das classes XmlSchemaElement e XmlSchemaAny.

Quando o compositor para o modelo de conteúdo é um xs:sequence, apenas a próxima partícula na sequência é retornada. Se o compositor para o modelo de conteúdo for um xs:all ou um xs:choice, todas as partículas válidas que poderiam seguir no contexto do elemento atual serão retornadas.

Observação

Se o método GetExpectedParticles for chamado imediatamente após chamar o método Initialize, o método GetExpectedParticles retornará todos os elementos globais.

Por exemplo, no esquema XSD (XML Schema Definition Language) e no documento XML que se seguem, depois de validar o elemento book, o elemento book é o contexto do elemento atual. O método GetExpectedParticles retorna uma matriz contendo um único objeto XmlSchemaElement que representa o elemento title. Quando o contexto de validação é o elemento title, o método GetExpectedParticles retorna uma matriz vazia. Se o método GetExpectedParticles for chamado depois que o elemento title tiver sido validado, mas antes que o elemento description tenha sido validado, ele retornará uma matriz contendo um único objeto XmlSchemaElement que representa o elemento description. Se o método GetExpectedParticles for chamado depois que o elemento description tiver sido validado, ele retornará uma matriz contendo um único objeto XmlSchemaAny que representa o curinga.

Dim reader As XmlReader =  XmlReader.Create("input.xml")

Dim schemaSet As New XmlSchemaSet()
schemaSet.Add(Nothing, "schema.xsd")
Dim manager As New XmlNamespaceManager(reader.NameTable)

Dim validator As New XmlSchemaValidator(reader.NameTable,schemaSet,manager,XmlSchemaValidationFlags.None)
validator.Initialize()

validator.ValidateElement("book", "", Nothing)

validator.ValidateEndOfAttributes(Nothing)
For Each element As XmlSchemaElement In validator.GetExpectedParticles()
    Console.WriteLine(element.Name)
Next

validator.ValidateElement("title", "", Nothing)
validator.ValidateEndOfAttributes(Nothing)
For Each element As XmlSchemaElement In validator.GetExpectedParticles()
    Console.WriteLine(element.Name)
Next
validator.ValidateEndElement(Nothing)

For Each element As XmlSchemaElement In validator.GetExpectedParticles()
    Console.WriteLine(element.Name)
Next

validator.ValidateElement("description", "", Nothing)
validator.ValidateEndOfAttributes(Nothing)
validator.ValidateEndElement(Nothing)

For Each particle As XmlSchemaParticle In validator.GetExpectedParticles()
    Console.WriteLine(particle.GetType())
Next

validator.ValidateElement("namespace", "", Nothing)
validator.ValidateEndOfAttributes(Nothing)
validator.ValidateEndElement(Nothing)

validator.ValidateEndElement(Nothing)
XmlReader reader = XmlReader.Create("input.xml");

var schemaSet = new XmlSchemaSet();
schemaSet.Add(null, "schema.xsd");
var manager = new XmlNamespaceManager(reader.NameTable);

var validator = new XmlSchemaValidator(reader.NameTable, schemaSet, manager, XmlSchemaValidationFlags.None);
validator.Initialize();

validator.ValidateElement("book", "", null);

validator.ValidateEndOfAttributes(null);
foreach (XmlSchemaElement element in validator.GetExpectedParticles())
{
    Console.WriteLine(element.Name);
}

validator.ValidateElement("title", "", null);
validator.ValidateEndOfAttributes(null);
foreach (XmlSchemaElement element in validator.GetExpectedParticles())
{
    Console.WriteLine(element.Name);
}
validator.ValidateEndElement(null);

foreach (XmlSchemaElement element in validator.GetExpectedParticles())
{
    Console.WriteLine(element.Name);
}

validator.ValidateElement("description", "", null);
validator.ValidateEndOfAttributes(null);
validator.ValidateEndElement(null);

foreach (XmlSchemaParticle particle in validator.GetExpectedParticles())
{
    Console.WriteLine(particle.GetType());
}

validator.ValidateElement("namespace", "", null);
validator.ValidateEndOfAttributes(null);
validator.ValidateEndElement(null);

validator.ValidateEndElement(null);

O exemplo usa o seguinte XML como entrada:

<xs:schema xmlns:xs="http://www.w3c.org/2001/XMLSchema">
  <xs:element name="book">
    <xs:sequence>
      <xs:element name="title" type="xs:string" />
      <xs:element name="description" type="xs:string" />
      <xs:any processContent="lax" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:element>
</xs:schema>

O exemplo usa o seguinte esquema XSD como entrada:

<book>
  <title>My Book</title>
  <description>My Book's Description</description>
  <namespace>System.Xml.Schema</namespace>
</book>

Observação

Os resultados dos métodos GetExpectedParticles, GetExpectedAttributese AddSchema da classe XmlSchemaValidator dependem do contexto atual que está sendo validado. Para obter mais informações, consulte a seção "Contexto de validação" deste tópico.

Para obter um exemplo do método GetExpectedParticles, veja o exemplo na introdução. Para obter mais informações sobre o método GetExpectedParticles, consulte a documentação de referência de classe XmlSchemaValidator.

Recuperando atributos esperados

O método GetExpectedAttributes retorna uma matriz de objetos XmlSchemaAttribute contendo os atributos esperados no contexto de elemento atual.

Por exemplo, no exemplo na introdução, o método GetExpectedAttributes é usado para recuperar todos os atributos do elemento book.

Se você chamar o método GetExpectedAttributes imediatamente após o método ValidateElement, todos os atributos que podem aparecer no documento XML serão retornados. No entanto, se você chamar o método GetExpectedAttributes após uma ou mais chamadas para o método ValidateAttribute, os atributos que ainda não foram validados para o elemento atual serão retornados.

Observação

Os resultados dos métodos GetExpectedParticles, GetExpectedAttributese AddSchema da classe XmlSchemaValidator dependem do contexto atual que está sendo validado. Para obter mais informações, consulte a seção "Contexto de validação" deste tópico.

Para obter um exemplo do método GetExpectedAttributes, veja o exemplo na introdução. Para obter mais informações sobre o método GetExpectedAttributes, consulte a documentação de referência de classe XmlSchemaValidator.

Recuperando atributos padrão não especificados

O método GetUnspecifiedDefaultAttributes preenche os ArrayList especificados com objetos XmlSchemaAttribute para quaisquer atributos com valores padrão que não tenham sido validados anteriormente usando o método ValidateAttribute no contexto do elemento. O método GetUnspecifiedDefaultAttributes deve ser chamado depois de chamar o método ValidateAttribute em cada atributo no contexto do elemento. O método GetUnspecifiedDefaultAttributes deve ser usado para determinar quais atributos padrão devem ser inseridos no documento XML que está sendo validado.

Para obter mais informações sobre o método GetUnspecifiedDefaultAttributes, consulte a documentação de referência de classe XmlSchemaValidator.

Manipulando eventos de validação de esquema

Os avisos de validação de esquema e os erros encontrados durante a validação são manipulados pelo evento ValidationEventHandler da classe XmlSchemaValidator.

Os avisos de validação de esquema têm um valor XmlSeverityType de Warning e os erros de validação de esquema têm um valor XmlSeverityType de Error. Se nenhum ValidationEventHandler tiver sido atribuído, será gerado um XmlSchemaValidationException para todos os erros de validação de esquema, com um valor XmlSeverityType de Error. No entanto, um XmlSchemaValidationException não é lançado para avisos de validação de esquema com um valor XmlSeverityType de Warning.

A seguir está um exemplo de um ValidationEventHandler que recebe avisos de validação de esquema e erros encontrados durante a validação de esquema extraídos do exemplo na introdução.

Shared Sub SchemaValidationEventHandler(sender As Object, e As ValidationEventArgs)

    Select Case e.Severity
        Case XmlSeverityType.Error
            Console.WriteLine(vbCrLf & "Error: {0}", e.Message)
            Exit Sub
        Case XmlSeverityType.Warning
            Console.WriteLine(vbCrLf & "Warning: {0}", e.Message)
            Exit Sub
    End Select
End Sub
static void SchemaValidationEventHandler(object sender, ValidationEventArgs e)
{
    switch (e.Severity)
    {
        case XmlSeverityType.Error:
            Console.WriteLine("\nError: {0}", e.Message);
            break;
        case XmlSeverityType.Warning:
            Console.WriteLine("\nWarning: {0}", e.Message);
            break;
    }
}

Para um exemplo completo do ValidationEventHandler, veja o exemplo na introdução. Para obter mais informações, consulte a documentação de referência de classe XmlSchemaInfo.

Transição de estado de XmlSchemaValidator

A classe XmlSchemaValidator tem uma transição de estado definida que impõe a sequência e a ocorrência de chamadas feitas para cada um dos métodos usados para validar elementos, atributos e conteúdo em um infoset XML.

A tabela a seguir descreve a transição de estado da classe XmlSchemaValidator e a sequência e ocorrência de chamadas de método que podem ser feitas em cada estado.

Estado Transição
Validar Initialize ValidateAttribute ( | Nível Superior*)EndValidation
Nível Superior ValidateWhitespace | ValidateText | Elemento
Elemento ValidateElement ValidateAttribute* (ValidateEndOfAttributes Conteúdo*)? ValidateEndElement |

ValidateElement ValidateAttribute * SkipToEndElement |

Conteúdo* ValidateElementValidateAttribute* ValidateEndOfAttributesSkipToEndElement |
Conteúdo ValidateWhitespace | ValidateText | Elemento

Observação

Um InvalidOperationException é lançado por cada um dos métodos na tabela acima quando a chamada para o método é feita na sequência incorreta de acordo com o estado atual de um objeto XmlSchemaValidator.

A tabela de transição de estado acima usa símbolos de pontuação para descrever os métodos e outros estados que podem ser chamados para cada estado da transição de estado da classe XmlSchemaValidator. Os símbolos usados são os mesmos símbolos encontrados na referência de padrões XML para definição de tipo de documento (DTD).

A tabela a seguir descreve como os símbolos de pontuação encontrados na tabela de transição de estado acima afetam os métodos e outros estados que podem ser chamados para cada estado na transição de estado da classe XmlSchemaValidator.

Símbolo Descrição
| Qualquer método ou estado (o anterior à barra ou o posterior) pode ser chamado.
? O método ou estado que precede o ponto de interrogação é opcional, mas se for chamado só pode ser chamado uma vez.
* O método ou estado que precede o símbolo * é opcional e pode ser chamado mais de uma vez.

Contexto de validação

Os métodos da classe XmlSchemaValidator usados para validar elementos, atributos e conteúdo em um infoset XML, alteram o contexto de validação de um objeto XmlSchemaValidator. Por exemplo, o método SkipToEndElement ignora a validação do conteúdo do elemento atual e prepara o objeto XmlSchemaValidator para validar o conteúdo no contexto do elemento pai; É equivalente a ignorar a validação para todos os filhos do elemento atual e, em seguida, chamar o método ValidateEndElement.

Os resultados dos métodos GetExpectedParticles, GetExpectedAttributese AddSchema da classe XmlSchemaValidator dependem do contexto atual que está sendo validado.

A tabela a seguir descreve os resultados da chamada desses métodos depois de chamar um dos métodos da classe XmlSchemaValidator usada para validar elementos, atributos e conteúdo em um infoset XML.

Método ObterPartículasEsperadas ObterAtributosEsperados AddSchema
Initialize Se o método Initialize padrão for chamado, GetExpectedParticles retornará uma matriz contendo todos os elementos globais.

Se o método Initialize sobrecarregado que usa um XmlSchemaObject como parâmetro for chamado para inicializar a validação parcial de um elemento, GetExpectedParticles retornará apenas o elemento para o qual o objeto XmlSchemaValidator foi inicializado.
Se o método Initialize padrão for chamado, GetExpectedAttributes retornará uma matriz vazia.

Se a sobrecarga do método Initialize que usa um XmlSchemaObject como parâmetro for chamada para inicializar a validação parcial de um atributo, GetExpectedAttributes retornará apenas o atributo ao qual o objeto XmlSchemaValidator foi inicializado.
Adiciona o esquema ao XmlSchemaSet do objeto XmlSchemaValidator se ele não tiver erros de pré-processamento.
ValidateElement Se o elemento de contexto for válido, GetExpectedParticles devolve a sequência de elementos esperados como filhos do elemento de contexto.

Se o elemento de contexto for inválido, GetExpectedParticles retornará uma matriz vazia.
Se o elemento de contexto for válido e se nenhuma chamada para ValidateAttribute tiver sido feita anteriormente, GetExpectedAttributes retornará uma lista de todos os atributos definidos no elemento de contexto.

Se alguns atributos já tiverem sido validados, GetExpectedAttributes retornará uma lista dos atributos restantes a serem validados.

Se o elemento de contexto for inválido, GetExpectedAttributes retornará uma matriz vazia.
Mesmo que acima.
ValidateAttribute Se o atributo context for um atributo de nível superior, GetExpectedParticles retornará uma matriz vazia.

Caso contrário, GetExpectedParticles retorna a sequência de elementos esperados como o primeiro filho do elemento de contexto.
Se o atributo context for um atributo de nível superior, GetExpectedAttributes retornará uma matriz vazia.

Caso contrárioGetExpectedAttributes retorna a lista de atributos restantes a serem validados.
Mesmo que acima.
GetUnspecifiedDefaultAttributes GetExpectedParticles retorna a sequência de elementos esperados como primeiro filho do elemento contexto. GetExpectedAttributes retorna uma lista dos atributos obrigatórios e opcionais que ainda precisam ser validados para o elemento context. Mesmo que acima.
ValidateEndOfAttributes GetExpectedParticles retorna a sequência de elementos esperados como primeiro filho do elemento contexto. GetExpectedAttributes retorna uma matriz vazia. Mesmo que acima.
ValidateText Se o contentType do elemento de contexto for Mixed, GetExpectedParticles retornará a sequência de elementos esperada na próxima posição.

Se o contentType do elemento de contexto for TextOnly ou Empty, GetExpectedParticles retornará uma matriz vazia.

Se o contentType do elemento de contexto for ElementOnly, GetExpectedParticles retornará a sequência de elementos esperada na próxima posição, mas já ocorreu um erro de validação.
GetExpectedAttributes retorna a lista de atributos não validados do elemento context. Mesmo que acima.
ValidateWhitespace Se o espaço em branco do contexto for espaço em branco de nível superior, GetExpectedParticles retornará uma matriz vazia.

Caso contrário, o comportamento do método GetExpectedParticles é o mesmo que em ValidateText.
Se o espaço em branco do contexto for espaço em branco de nível superior, GetExpectedAttributes retornará uma matriz vazia.

Caso contrário, o comportamento do método GetExpectedAttributes é o mesmo que em ValidateText.
Mesmo que acima.
ValidateEndElement GetExpectedParticles retorna a sequência de elementos esperados após o elemento de contexto (possíveis irmãos). GetExpectedAttributes retorna a lista de atributos não validados do elemento context.

Se o elemento de contexto não tiver pai, GetExpectedAttributes retornará uma lista vazia (o elemento de contexto é o pai do elemento atual no qual ValidateEndElement foi chamado).
Mesmo que acima.
SkipToEndElement O mesmo que ValidateEndElement. O mesmo que ValidateEndElement. Mesmo que acima.
EndValidation Retorna uma matriz vazia. Retorna uma matriz vazia. Mesmo que acima.

Observação

Os valores retornados pelas várias propriedades da classe XmlSchemaValidator não são alterados chamando qualquer um dos métodos na tabela acima.

Ver também