Share via


Validación basada en inserción de XmlSchemaValidator

La clase XmlSchemaValidator incluye un mecanismo eficiente y de alto rendimiento para validar datos XML con esquemas XML mediante inserción. Por ejemplo, la clase XmlSchemaValidator le permite validar un conjunto de información XML en el lugar sin tener que serializarla como un documento XML y, a continuación, volver a analizar el documento utilizando un sistema de lectura XML de validación.

La clase XmlSchemaValidator se puede utilizar en situaciones avanzadas como, por ejemplo, durante la creación de motores de validación en orígenes de datos XML o como forma de crear un sistema de escritura XML de validación.

A continuación se ofrece un ejemplo del uso de la clase XmlSchemaValidator para validar el archivo contosoBooks.xml con el esquema contosoBooks.xsd. El ejemplo utiliza la clase XmlSerializer para deserializar el archivo contosoBooks.xml y pasar el valor de los nodos a los métodos de la clase XmlSchemaValidator.

Nota

Este ejemplo se utiliza a lo largo de las secciones de este tema.

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: '{0}'", 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 '{0}' with type '{1}' is '{2}'",
                    schemaInfo.SchemaElement.Name, schemaInfo.SchemaType, schemaInfo.Validity);
            }
            else if (schemaInfo.SchemaAttribute != null)
            {
                Console.WriteLine("Attribute '{0}' with type '{1}' is '{2}'",
                    schemaInfo.SchemaAttribute.Name, schemaInfo.SchemaType, schemaInfo.Validity);
            }
        }

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

    [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

En el ejemplo se toma como entrada el archivo 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>

En el ejemplo también se toma como entrada el archivo 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>

Validación de datos XML con XmlSchemaValidator

Para comenzar la validación de un conjunto de información XML, primero se debe inicializar una instancia nueva de la clase XmlSchemaValidator utilizando el constructor XmlSchemaValidator.

El constructor XmlSchemaValidator toma los objetos XmlNameTable, XmlSchemaSet y XmlNamespaceManager como parámetros, así como un valor XmlSchemaValidationFlags como parámetro. El objeto XmlNameTable se utiliza para atomizar cadenas de espacios de nombres bien conocidas (como el espacio de nombres del esquema, el espacio de nombres XML, etc.), y se pasa al método ParseValue mientras se valida contenido simple. El objeto XmlSchemaSet contiene los esquemas XML que se utilizan para validar el conjunto de información XML. El objeto XmlNamespaceManager se utiliza para resolver espacios de nombres que se encuentran durante la validación. El valor XmlSchemaValidationFlags se utiliza para deshabilitar determinadas características de la validación.

Para obtener más información sobre el constructor XmlSchemaValidator, vea la documentación de referencia de la clase XmlSchemaValidator.

Inicialización de la validación

Una vez construido un objeto XmlSchemaValidator, existen dos métodos Initialize sobrecargados que se utilizan para inicializar el estado del objeto XmlSchemaValidator. Éstos son los dos métodos Initialize.

El método XmlSchemaValidator.Initialize predeterminado inicializa un objeto XmlSchemaValidator en su estado inicial y el método XmlSchemaValidator.Initialize sobrecargado, que toma un XmlSchemaObject como parámetro, inicializa un objeto XmlSchemaValidator en su estado inicial para realizar una validación parcial.

Los dos métodos Initialize solo se pueden llamar inmediatamente después de construir un objeto XmlSchemaValidator o después de una llamada a EndValidation.

Para obtener un ejemplo del método XmlSchemaValidator.Initialize, vea el ejemplo de la introducción. Para obtener más información sobre el método Initialize, vea la documentación de referencia de la clase XmlSchemaValidator.

Validación parcial

El método XmlSchemaValidator.Initialize que toma un objeto XmlSchemaObject como parámetro inicializa un objeto XmlSchemaValidator en su estado inicial para realizar una validación parcial.

En el siguiente ejemplo, se inicializa un XmlSchemaObject para realizar una validación parcial utilizando el método XmlSchemaValidator.Initialize. Para pasar el elemento de esquema orderNumber, se selecciona por XmlQualifiedName en la colección XmlSchemaObjectTable que devuelve la propiedad GlobalElements del objeto XmlSchemaSet. A continuación, el objeto XmlSchemaValidator valida este 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);

En el ejemplo, se toma como entrada el siguiente esquema XML.

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

Para obtener más información sobre el método Initialize, vea la documentación de referencia de la clase XmlSchemaValidator.

Adición de esquemas adicionales

El método AddSchema de la clase XmlSchemaValidator se utiliza para agregar un esquema XML al conjunto de esquemas que se utiliza durante la validación. El método AddSchema se puede utilizar para simular el efecto de encontrarse un esquema XML alineado en el conjunto de información XML que se está validando.

Nota

El espacio de nombres de destino del parámetro XmlSchema no puede coincidir con el de ningún elemento o atributo que ya haya encontrado el objeto XmlSchemaValidator.

Si el valor XmlSchemaValidationFlags.ProcessInlineSchema no se hubiera pasado como parámetro al constructor XmlSchemaValidator, el método AddSchema no haría nada.

El resultado del método AddSchema depende del contexto del nodo XML actual que se está validando. Para obtener más información sobre los contextos de validación, vea la sección "Contexto de validación" en este tema.

Para obtener más información sobre el método AddSchema, vea la documentación de referencia de la clase XmlSchemaValidator.

Validación de elementos, atributos y contenido

La clase XmlSchemaValidator incluye varios métodos que se utilizan para validar elementos, atributos y contenido en un conjunto de información XML con esquemas XML. En la siguiente tabla se describen cada uno de estos métodos.

Método Descripción
ValidateElement Valida el nombre del elemento en el contexto actual.
ValidateAttribute Valida el atributo en el contexto del elemento actual o con el objeto XmlSchemaAttribute que se pasa como parámetro al método Initialize.
ValidateEndOfAttributes Comprueba si todos los atributos requeridos del contexto del elemento están presentes y prepara el objeto XmlSchemaValidator para validar el contenido secundario del elemento.
ValidateText Valida si se permite texto en el contexto del elemento actual y acumula el texto para validar si el elemento actual tiene contenido simple.
ValidateWhitespace Valida si se permite espacio en blanco en el contexto del elemento actual y acumula el espacio en blanco para validar si el elemento actual tiene contenido simple.
ValidateEndElement Comprueba si el contenido de texto del elemento es válido de acuerdo con su tipo de datos para elementos con contenido simple, y comprueba si el contenido del elemento actual está completo para los elementos con contenido complejo.
SkipToEndElement Omite la validación del contenido del elemento actual y prepara el objeto XmlSchemaValidator para validar contenido en el contexto del elemento primario.
EndValidation Termina la validación y comprueba las restricciones de identidad de todo el documento XML si se establece la opción de validación ProcessIdentityConstraints.

Nota

La clase XmlSchemaValidator tiene una transición de estado definida que exige la secuencia y ocurrencia de las llamadas realizadas a cada uno de los métodos que se describen en la tabla anterior. La transición de estado específica de la clase XmlSchemaValidator se describe en la sección "Transición de estado de XmlSchemaValidator" de este tema.

Para obtener un ejemplo de los métodos que se utilizan para validar elementos, atributos y contenido en un conjunto de información XML, vea el ejemplo de la sección anterior. Para obtener más información sobre estos métodos, vea la documentación de referencia de la clase XmlSchemaValidator.

Validación de contenido con XmlValueGetter

XmlValueGetterdelegate se puede utilizar para pasar el valor de los nodos de atributos, textos o espacios en blanco como tipos Common Language Runtime (CLR) compatibles con el tipo del lenguaje de definición de esquema XML (XSD) del nodo de atributos, textos o espacios en blanco. XmlValueGetterdelegate es útil si el valor CLR de un nodo de atributos, textos o espacios en blanco ya está disponible y evita el costo de convertirlo en un valor string y luego volver a analizarlo para validarlo.

Los métodos ValidateAttribute, ValidateText y ValidateWhitespace están sobrecargados y aceptan el valor de los nodos de atributos, textos o espacios en blanco como un string o XmlValueGetterdelegate.

Los siguientes métodos de la clase XmlSchemaValidator aceptan un XmlValueGetterdelegate como parámetro.

A continuación, se ofrece un ejemplo de un XmlValueGetterdelegate tomado del ejemplo de la clase XmlSchemaValidator de la introducción. XmlValueGetterdelegate devuelve el valor de un atributo como un objeto DateTime. Para validar este objeto DateTime que devuelve XmlValueGetter, el objeto XmlSchemaValidator primero lo convierte en ValueType (ValueType es la asignación CLR predeterminada para el tipo XSD) para el tipo de datos del atributo y, a continuación, comprueba las facetas en el 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 obtener un ejemplo completo de XmlValueGetterdelegate, vea el ejemplo de la introducción. Para obtener más información sobre XmlValueGetterdelegate, vea la documentación de referencia de las clases XmlValueGetter y XmlSchemaValidator.

Información posterior a la validación del esquema

La clase XmlSchemaInfo representa parte de la información posterior a la validación del esquema de un nodo XML que valida la clase XmlSchemaValidator. Hay varios métodos de la clase XmlSchemaValidator que aceptan un objeto XmlSchemaInfo como un parámetro null opcional (out).

Después de realizar la validación correctamente, se establecen las propiedades del objeto XmlSchemaInfo con los resultados de la validación. Por ejemplo, después de validar correctamente un atributo utilizando el método ValidateAttribute, las propiedades XmlSchemaInfo, SchemaAttribute, SchemaType y MemberType del objeto Validity se establecen con los resultados de la validación.

Los siguientes métodos de la clase XmlSchemaValidator aceptan un objeto XmlSchemaInfo como parámetro out.

Para obtener un ejemplo completo de la clase XmlSchemaInfo, vea el ejemplo de la introducción. Para obtener más información sobre la clase XmlSchemaInfo, vea la documentación de referencia de la clase XmlSchemaInfo.

Recuperación de partículas y atributos esperados y atributos predeterminados no especificados

La clase XmlSchemaValidator proporciona los métodos GetExpectedAttributes, GetExpectedParticles y GetUnspecifiedDefaultAttributes para recuperar las partículas y atributos esperados y los atributos predeterminados no especificados en el contexto de validación actual.

Recuperación de partículas esperadas

El método GetExpectedParticles devuelve una matriz de objetos XmlSchemaParticle que contienen las partículas esperadas en el contexto del elemento actual. Las partículas válidas que puede devolver el método GetExpectedParticles son instancias de las clases XmlSchemaElement y XmlSchemaAny.

Cuando el compositor del modelo de contenido es xs:sequence, solo se devuelve la siguiente partícula de la secuencia. Si el compositor del modelo de contenido es xs:all o xs:choice, se devuelven todas las partículas válidas que pueden ir a continuación en el contexto del elemento actual.

Nota

Si se llama al método GetExpectedParticles inmediatamente después de llamar al método Initialize, el método GetExpectedParticles devuelve todos los elementos globales.

Por ejemplo, en el esquema del lenguaje de definición de esquemas XML (XSD) y en el documento XML que sigue, después de validar el elemento book, el elemento book es el contexto del elemento actual. El método GetExpectedParticles devuelve una matriz que contiene un solo objeto XmlSchemaElement que representa el elemento title. Cuando el contexto de validación es el elemento title, el método GetExpectedParticles devuelve una matriz vacía. Si se llama al método GetExpectedParticles después de que se haya validado el elemento title, pero antes de validar el elemento description, devuelve una matriz que contiene un solo objeto XmlSchemaElement que representa el elemento description. Si se llama al método GetExpectedParticles después de que se haya validado el elemento description, devuelve una matriz que contiene un solo objeto XmlSchemaAny que representa el comodín.

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

En el ejemplo se toma como entrada el siguiente XML:

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

En el ejemplo se toma como entrada el siguiente esquema XSD:

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

Nota

Los resultados de los métodos GetExpectedParticles, GetExpectedAttributes y AddSchema de la clase XmlSchemaValidator dependen del contexto actual que se está validando. Para obtener más información, vea la sección "Contexto de validación" de este tema.

Para obtener un ejemplo del método GetExpectedParticles, vea el ejemplo de la introducción. Para obtener más información sobre el método GetExpectedParticles, vea la documentación de referencia de la clase XmlSchemaValidator.

Recuperación de atributos esperados

El método GetExpectedAttributes devuelve una matriz de objetos XmlSchemaAttribute que contienen los atributos esperados en el contexto del elemento actual.

Por ejemplo, en el ejemplo de la introducción, se utiliza el método GetExpectedAttributes para recuperar todos los atributos del elemento book.

Si llama al método GetExpectedAttributes inmediatamente después del método ValidateElement, se devuelven todos los atributos que podrían aparecer en el documento XML. Sin embargo, si llama al método GetExpectedAttributes después de una o más llamadas al método ValidateAttribute, se devuelven los atributos que aún no se han validado para el elemento actual.

Nota

Los resultados de los métodos GetExpectedParticles, GetExpectedAttributes y AddSchema de la clase XmlSchemaValidator dependen del contexto actual que se está validando. Para obtener más información, vea la sección "Contexto de validación" de este tema.

Para obtener un ejemplo del método GetExpectedAttributes, vea el ejemplo de la introducción. Para obtener más información sobre el método GetExpectedAttributes, vea la documentación de referencia de la clase XmlSchemaValidator.

Recuperación de atributos predeterminados no especificados

El método GetUnspecifiedDefaultAttributes rellena el ArrayList especificado con objetos XmlSchemaAttribute para cualquier atributo con valores predeterminados que no haya sido validado previamente con el método ValidateAttribute en el contexto del elemento. El método GetUnspecifiedDefaultAttributes se debería llamar después de llamar al método ValidateAttribute en cada atributo del contexto del elemento. El método GetUnspecifiedDefaultAttributes se debería utilizar para determinar qué atributos predeterminados se van a insertar en el documento XML que se está validando.

Para obtener más información sobre el método GetUnspecifiedDefaultAttributes, vea la documentación de referencia de la clase XmlSchemaValidator.

Control de eventos de validación de esquemas

Las advertencias y errores de validación de esquemas que se encuentran durante la validación se controlan por medio del evento ValidationEventHandler de la clase XmlSchemaValidator.

Las advertencias de validación de esquemas tienen un valor XmlSeverityType de Warning y los errores de validación de esquemas tienen un valor XmlSeverityType de Error. Si no se ha asignado ningún ValidationEventHandler, se inicia una XmlSchemaValidationException para todos los errores de validación de esquemas con un valor XmlSeverityType de Error. Sin embargo, no se inicia una XmlSchemaValidationException para las advertencias de validación de esquemas con un valor XmlSeverityType de Warning.

A continuación, se ofrece un ejemplo de un ValidationEventHandler que recibe errores y advertencias de validación de esquemas que se encuentran durante la validación de esquemas tomada del ejemplo de la introducción.

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 obtener un ejemplo completo de ValidationEventHandler, vea el ejemplo de la introducción. Para obtener más información, vea la documentación de referencia de la clase XmlSchemaInfo.

Transición de estado de XmlSchemaValidator

La clase XmlSchemaValidator tiene una transición de estado definida que exige la secuencia y ocurrencia de las llamadas realizadas a cada uno de los métodos que se utilizan para validar elementos, atributos y contenido en un conjunto de información XML.

En la siguiente tabla se describe la transición de estado de la clase XmlSchemaValidator y la secuencia y ocurrencia de las llamadas de método que se pueden realizar en cada estado.

Estado Transición
Validar Initialize (ValidateAttribute | TopLevel*) EndValidation
TopLevel ValidateWhitespace | ValidateText | Element
Elemento ValidateElementValidateAttribute* (ValidateEndOfAttributes Content*)? ValidateEndElement |

ValidateElement ValidateAttribute* SkipToEndElement |

ValidateElementValidateAttribute* ValidateEndOfAttributes Content* SkipToEndElement |
Contenido ValidateWhitespace | ValidateText | Element

Nota

Cada uno de los métodos de la tabla anterior inicia una InvalidOperationException cuando se realiza la llamada al método en la secuencia incorrecta de acuerdo con el estado actual de un objeto XmlSchemaValidator.

La tabla de transición de estado anterior utiliza signos de puntuación para describir los métodos y otros estados que se pueden llamar para cada estado de la transición de la clase XmlSchemaValidator. Los signos que se utilizan son los mismos que se encuentran en la referencia de estándares XML de la definición de tipos de documento (DTD).

En la siguiente tabla se describe cómo los signos de puntuación que se encuentran en la tabla de transiciones de estado anterior afectan a los métodos y otros estados que se pueden llamar para cada estado de la transición de la clase XmlSchemaValidator.

Símbolo Descripción
| Se puede llamar al método o al estado (al que está antes o después de la barra).
? El método o estado que precede al signo de interrogación es opcional, pero si se llama, solo se puede llamar una vez.
* El método o estado que precede al símbolo * es opcional y se puede llamar más de una vez.

Contexto de validación

Los métodos de la clase XmlSchemaValidator que se utilizan para validar elementos, atributos y contenido en un conjunto de información XML cambian el contexto de validación de un objeto XmlSchemaValidator. Por ejemplo, el método SkipToEndElement omite la validación del contenido del elemento actual y prepara el objeto XmlSchemaValidator para validar contenido en el contexto del elemento primario; es equivalente a la omisión de la validación para todos los elementos secundarios del elemento actual y luego a la llamada del método ValidateEndElement.

Los resultados de los métodos GetExpectedParticles, GetExpectedAttributes y AddSchema de la clase XmlSchemaValidator dependen del contexto actual que se está validando.

En la siguiente tabla se describen los resultados de las llamadas a estos métodos después de llamar a uno de los métodos de la clase XmlSchemaValidator que se utiliza para validar elementos, atributos y contenido en un conjunto de información XML.

Método GetExpectedParticles GetExpectedAttributes AddSchema
Initialize Si se llama al método Initialize predeterminado, GetExpectedParticles devuelve una matriz que contiene todos los elementos globales.

Si se llama al método Initialize sobrecargado que toma un XmlSchemaObject como parámetro para inicializar la validación parcial de un elemento, GetExpectedParticles devuelve solo el elemento en el cual se ha inicializado el objeto XmlSchemaValidator.
Si se llama al método Initialize predeterminado, GetExpectedAttributes devuelve una matriz vacía.

Si se llama a la sobrecarga del método Initialize que toma un XmlSchemaObject como parámetro para inicializar la validación parcial de un atributo, GetExpectedAttributes devuelve solo el atributo en el cual se ha inicializado el objeto XmlSchemaValidator.
Agrega el esquema al XmlSchemaSet del objeto XmlSchemaValidator si no tiene errores de procesamiento previo.
ValidateElement Si el elemento del contexto es válido, GetExpectedParticles devuelve la secuencia de elementos esperada como elementos secundarios del elemento del contexto.

Si el elemento del contexto no es válido, GetExpectedParticles devuelve una matriz vacía.
Si el elemento del contexto es válido, y si no se ha realizado previamente ninguna llamada a ValidateAttribute, GetExpectedAttributes devuelve una lista de todos los atributos definidos en el elemento del contexto.

Si ya se han validado algunos atributos, GetExpectedAttributes devuelve una lista de los atributos restantes que hay que validar.

Si el elemento del contexto no es válido, GetExpectedAttributes devuelve una matriz vacía.
Como anteriormente.
ValidateAttribute Si el atributo del contexto es un atributo de nivel superior, GetExpectedParticles devuelve una matriz vacía.

De lo contrario, GetExpectedParticles devuelve la secuencia de elementos esperada como primer elemento secundario del elemento del contexto.
Si el atributo del contexto es un atributo de nivel superior, GetExpectedAttributes devuelve una matriz vacía.

De lo contrario, GetExpectedAttributes devuelve la lista de atributos restantes que hay que validar.
Como anteriormente.
GetUnspecifiedDefaultAttributes GetExpectedParticles devuelve la secuencia de elementos esperada como primer elemento secundario del elemento del contexto. GetExpectedAttributes devuelve una lista de los atributos requeridos y opcionales que aún quedan por validar en el elemento del contexto. Como anteriormente.
ValidateEndOfAttributes GetExpectedParticles devuelve la secuencia de elementos esperada como primer elemento secundario del elemento del contexto. GetExpectedAttributes devuelve una matriz vacía. Como anteriormente.
ValidateText Si contentType del elemento del contexto es Mixed, GetExpectedParticles devuelve la secuencia de elementos esperada en la siguiente posición.

Si contentType del elemento del contexto es TextOnly o Empty, GetExpectedParticles devuelve una matriz vacía.

Si contentType del elemento del contexto es ElementOnly, GetExpectedParticles devuelve la secuencia de elementos esperada en la siguiente posición, pero ya se ha producido un error de validación.
GetExpectedAttributes devuelve la lista de atributos del elemento del contexto no validada. Como anteriormente.
ValidateWhitespace Si el espacio en blanco del contexto es un espacio en blanco de nivel superior, GetExpectedParticles devuelve una matriz vacía.

De lo contrario, el comportamiento del método GetExpectedParticles es el mismo que en ValidateText.
Si el espacio en blanco del contexto es un espacio en blanco de nivel superior, GetExpectedAttributes devuelve una matriz vacía.

De lo contrario, el comportamiento del método GetExpectedAttributes es el mismo que en ValidateText.
Como anteriormente.
ValidateEndElement GetExpectedParticles devuelve la secuencia de elementos esperada después del elemento del contexto (posibles elementos relacionados). GetExpectedAttributes devuelve la lista de atributos del elemento del contexto no validada.

Si el elemento del contexto no tiene elemento primario, GetExpectedAttributes devuelve una lista vacía (el elemento del contexto es el elemento primario del elemento actual en el que se ha llamado a ValidateEndElement).
Como anteriormente.
SkipToEndElement Igual a ValidateEndElement. Igual a ValidateEndElement. Como anteriormente.
EndValidation Devuelve una matriz vacía. Devuelve una matriz vacía. Como anteriormente.

Nota

Los valores devueltos por las diversas propiedades de la clase XmlSchemaValidator no cambian al llamar a cualquiera de los métodos de la tabla anterior.

Vea también