Принудительная проверка с помощью XmlSchemaValidator

Класс XmlSchemaValidator предоставляет эффективный, высокопроизводительный механизм для принудительной проверки XML-данных по схемам XML. Например, класс XmlSchemaValidator позволяет проверять информационный набор XML локально, без сериализации в виде XML-документа, а затем повторно выполнить синтаксический анализ с помощью проверяющего модуля чтения XML.

Класс XmlSchemaValidator можно использовать в расширенных сценариях, например, для создания подсистем проверки в пользовательских источниках XML-данных или проверяющего модуля записи XML.

В следующем примере класс XmlSchemaValidator используется для проверки файла contosoBooks.xml по схеме contosoBooks.xsd. Класс XmlSerializer в примере используется для десериализации файла contosoBooks.xml и передачи значений узлов методам класса XmlSchemaValidator.

Примечание.

Этот пример приводится во всех подразделах этого раздела.

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

В примере в качестве входных данных используется файл contosoBooks.xml.

<?xml version="1.0" encoding="utf-8" ?>
<bookstore xmlns="http://www.contoso.com/books">
    <book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
        <title>The Autobiography of Benjamin Franklin</title>
        <author>
            <first-name>Benjamin</first-name>
            <last-name>Franklin</last-name>
        </author>
        <price>8.99</price>
    </book>
    <book genre="novel" publicationdate="1967-11-17" ISBN="0-201-63361-2">
        <title>The Confidence Man</title>
        <author>
            <first-name>Herman</first-name>
            <last-name>Melville</last-name>
        </author>
        <price>11.99</price>
    </book>
    <book genre="philosophy" publicationdate="1991-02-15" ISBN="1-861001-57-6">
        <title>The Gorgias</title>
        <author>
            <name>Plato</name>
        </author>
        <price>9.99</price>
    </book>
</bookstore>

В примере также в качестве входных данных используется contosoBooks.xsd.

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.contoso.com/books" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="bookstore">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="book">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="title" type="xs:string" />
                            <xs:element name="author">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element minOccurs="0" name="name" type="xs:string" />
                                        <xs:element minOccurs="0" name="first-name" type="xs:string" />
                                        <xs:element minOccurs="0" name="last-name" type="xs:string" />
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                            <xs:element name="price" type="xs:decimal" />
                        </xs:sequence>
                        <xs:attribute name="genre" type="xs:string" use="required" />
                        <xs:attribute name="publicationdate" type="xs:date" use="required" />
                        <xs:attribute name="ISBN" type="xs:string" use="required" />
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

Проверка XML-данных с помощью XmlSchemaValidator

Чтобы начать проверку информационного набора XML, необходимо вначале инициализировать новый экземпляр класса XmlSchemaValidator с помощью конструктора XmlSchemaValidator.

Конструктор XmlSchemaValidator принимает объекты XmlNameTable, XmlSchemaSet и XmlNamespaceManager, а также значение XmlSchemaValidationFlags в качестве параметра. Объект XmlNameTable используется для атомизации известных строк пространств имен (таких как пространство имен схемы, пространство имен XML и так далее) и передает их методу ParseValue при проверке простого содержимого. Объект XmlSchemaSet содержит схемы XML, используемые при проверке информационного набора XML. Объект XmlNamespaceManager применяется для разрешения пространства имен во время проверки. Значение XmlSchemaValidationFlags используется для отключения определенных функций проверки.

Дополнительные сведения о конструкторе XmlSchemaValidator см. в справочной документации по классу XmlSchemaValidator.

Инициализация проверки

После создания объект XmlSchemaValidator имеет два перегруженных метода Initialize, которые применяются для инициализации состояния объекта XmlSchemaValidator. Ниже представлены два этих метода Initialize.

Метод XmlSchemaValidator.Initialize, применяющийся по умолчанию, инициализирует начальное состояние объекта XmlSchemaValidator, а перегруженный метод XmlSchemaValidator.Initialize, принимающий в качестве параметра XmlSchemaObject, инициализирует начальное состояние объекта XmlSchemaValidator для частичной проверки.

Оба метода Initialize можно вызвать только сразу после создания объекта XmlSchemaValidator или вызова EndValidation.

Пример метода XmlSchemaValidator.Initialize см. в примере во введении. Дополнительные сведения о методе Initialize см. в справочной документации по классу XmlSchemaValidator.

Частичная проверка

Метод XmlSchemaValidator.Initialize, принимающий в качестве параметра XmlSchemaObject, инициализирует начальное состояние объекта XmlSchemaValidator для частичной проверки.

В следующем примере объект XmlSchemaObject инициализируется для частичной проверки с помощью метода XmlSchemaValidator.Initialize. Элемент схемы orderNumber передается путем выбора XmlQualifiedName в коллекции XmlSchemaObjectTable, возвращаемой свойством GlobalElements объекта XmlSchemaSet. Затем объект XmlSchemaValidator проверяет этот элемент.

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

Этот пример принимает в качестве входных данных следующую схему XML.

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

Дополнительные сведения о методе Initialize см. в справочной документации по классу XmlSchemaValidator.

Добавление дополнительных схем

Метод AddSchema класса XmlSchemaValidator используется для добавления схемы XML в набор схем, который применяется во время проверки. Метод AddSchema может использоваться для моделирования результата обнаружения встроенной схемы XML в проверяемом информационном наборе XML.

Примечание.

Целевое пространство имен параметра XmlSchema не может соответствовать пространству имен элемента или атрибута, уже обнаруженного объектом XmlSchemaValidator.

Если значение XmlSchemaValidationFlags.ProcessInlineSchema не было передано в качестве параметра конструктору XmlSchemaValidator, метод AddSchema не предпринимает никаких действий.

Результат метода AddSchema зависит от текущего контекста проверяемого XML-узла. Дополнительные сведения о контексте проверки см. в подразделе «Контекст проверки» этого раздела.

Дополнительные сведения о методе AddSchema см. в справочной документации по классу XmlSchemaValidator.

Проверка элементов, атрибутов и содержимого

Класс XmlSchemaValidator предоставляет несколько методов для проверки по схемам XML элементов, атрибутов и содержимого информационного набора XML. В следующей таблице описан каждый из этих методов.

Метод Description
ValidateElement Проверяет имя элемента в текущем контексте.
ValidateAttribute Проверяет атрибут в контексте текущего элемента или по объекту XmlSchemaAttribute, переданному в качестве параметра методу Initialize.
ValidateEndOfAttributes Проверяет наличие всех необходимых атрибутов в контексте элемента и подготавливает объект XmlSchemaValidator для проверки содержимого дочернего элемента.
ValidateText Проверяет, разрешен ли текст в контексте текущего элемента и накапливает текст для проверки, если текущий элемент имеет простое содержимое.
ValidateWhitespace Проверяет, разрешены ли пробелы в контексте текущего элемента и накапливает пробелы для проверки, если текущий элемент имеет простое содержимое.
ValidateEndElement Проверяет допустимость текстового содержимого элемента с простым содержимым и полноту содержимого текущего элемента для элементов со сложным содержимым.
SkipToEndElement Пропускает проверку содержимого текущего элемента и подготавливает объект XmlSchemaValidator для проверки содержимого в контексте родительского элемента.
EndValidation Завершает проверку и проверяет ограничения удостоверения для всего XML-документа, если указан параметр проверки ProcessIdentityConstraints.

Примечание.

В классе XmlSchemaValidator объявляется переход между состояниями, определяющий последовательность и вхождение вызовов каждого метода, описанного в приведенной выше таблице. Специальный переход между состояниями класса XmlSchemaValidator описан в подразделе «Переход между состояниями XmlSchemaValidator» этого раздела.

Пример методов, которые используются для проверки элементов, атрибутов и содержимого в информационном наборе XML, см. в примерах предыдущего раздела. Дополнительные сведения об этих методах см. в справочной документации по классу XmlSchemaValidator.

Проверка содержимого с помощью XmlValueGetter

XmlValueGetterdelegate может использоваться для передачи значения узла атрибута, текста или пробела как типов CLR, совместимых с типами XSD для узла атрибута, текста или пробела. XmlValueGetterdelegate полезно использовать, если значение CLR узла атрибута, текста или пробела уже доступно, так как это позволяет избежать затрат на преобразование в тип string и последующий повторный синтаксический анализ для проверки.

Методы ValidateAttribute, ValidateText и ValidateWhitespace перегружены и принимают значение узла атрибута, текста или пробела как тип string или XmlValueGetterdelegate.

Следующие методы класса XmlSchemaValidator принимают XmlValueGetterdelegate в качестве параметра.

Следующий пример XmlValueGetterdelegate взят из примера класса XmlSchemaValidator во введении. XmlValueGetterdelegate возвращает значение атрибута в виде объекта DateTime. Для проверки объекта DateTime, возвращенного XmlValueGetter, объект XmlSchemaValidator вначале преобразует его в тип ValueType для типа данных атрибута (ValueType является сопоставлением CLR по умолчанию для типа XSD), а затем проверяет аспекты в преобразованном значении.

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

Полный пример XmlValueGetterdelegate см. во введении. Дополнительные сведения о XmlValueGetterdelegate см. в справочной документации по классам XmlValueGetter и XmlSchemaValidator.

Post-Schema-Validation-Information

Класс XmlSchemaInfo представляет некоторые сведения после проверки схемы XML-узла, проверенного классом XmlSchemaValidator. Различные методы класса XmlSchemaValidator принимают объект XmlSchemaInfo в качестве необязательного (null) параметра типа out.

По окончании успешной проверки свойства объекта XmlSchemaInfo принимают значения результатов проверки. Например, по окончании успешной проверки атрибута с помощью метода ValidateAttribute, свойства XmlSchemaInfo, SchemaAttribute, SchemaType и MemberType (если они заданы) объекта Validity принимают значения результатов проверки.

Следующие методы класса XmlSchemaValidator принимают объект XmlSchemaInfo в качестве выходного параметра.

Полный пример класса XmlSchemaInfo см. во введении. Дополнительные сведения о классе XmlSchemaInfo см. в справочной документации по классу XmlSchemaInfo.

Получение ожидаемых примитивов, атрибутов и неуказанных атрибутов по умолчанию

Класс XmlSchemaValidator предоставляет методы GetExpectedAttributes, GetExpectedParticles и GetUnspecifiedDefaultAttributes для получения ожидаемых примитивов, атрибутов и неуказанных атрибутов по умолчанию в текущем контексте проверки.

Получение ожидаемых примитивов

Метод GetExpectedParticles возвращает массив объектов XmlSchemaParticle, содержащих ожидаемые примитивы в текущем контекстном элементе. Допустимыми примитивами, возвращаемыми методом GetExpectedParticles, являются экземпляры классов XmlSchemaElement и XmlSchemaAny.

Если компоновщиком модели содержимого является xs:sequence, возвращается только следующий примитив последовательности. Если компоновщиком модели содержимого является xs:all или xs:choice, возвращаются все допустимые примитивы, которые могут следовать в текущем контекстном элементе.

Примечание.

Если метод GetExpectedParticles вызывается сразу после вызова Initialize метода GetExpectedParticles, он возвращает все глобальные элементы.

Например, в следующей схеме XSD и XML-документе после проверки элемента book текущим контекстным элементом является элемент book. Метод GetExpectedParticles возвращает массив, который содержит один объект XmlSchemaElement, представляющий элемент title. Если контекстом проверки является элемент title, метод GetExpectedParticles возвращает пустой массив. Если метод GetExpectedParticles вызывается после проверки элемента title, но перед проверкой элемента description, он возвращает массив, который содержит один объект XmlSchemaElement, представляющий элемент description. Если метод GetExpectedParticles вызывается после проверки элемента description, он возвращает массив, который содержит один объект XmlSchemaAny, представляющий символ-шаблон.

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

Этот пример принимает в качестве входных данных следующий 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>

Этот пример принимает в качестве входных данных следующую схему XSD:

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

Примечание.

Результаты выполнения методов GetExpectedParticles, GetExpectedAttributes и AddSchema класса XmlSchemaValidator зависят от текущего подвергаемого проверке контекста. Дополнительные сведения см. в подразделе «Контекст проверки» в данном разделе.

Пример метода GetExpectedParticles см. в примере во введении. Дополнительные сведения о методе GetExpectedParticles см. в справочной документации по классу XmlSchemaValidator.

Получение ожидаемых атрибутов

Метод GetExpectedAttributes возвращает массив объектов XmlSchemaAttribute, содержащих ожидаемые атрибуты в текущем контекстном элементе.

Например, в примере во введении метод GetExpectedAttributes используется для получения всех атрибутов элемента book.

Если метод GetExpectedAttributes вызывается сразу после метода ValidateElement, возвращаются все атрибуты, которые могут встретиться в XML-документе. Но если метод GetExpectedAttributes вызывается после одного или нескольких вызовов метода ValidateAttribute, возвращаются еще не проверенные атрибуты текущего элемента.

Примечание.

Результаты выполнения методов GetExpectedParticles, GetExpectedAttributes и AddSchema класса XmlSchemaValidator зависят от текущего подвергаемого проверке контекста. Дополнительные сведения см. в подразделе «Контекст проверки» в данном разделе.

Пример метода GetExpectedAttributes см. в примере во введении. Дополнительные сведения о методе GetExpectedAttributes см. в справочной документации по классу XmlSchemaValidator.

Получение неуказанных атрибутов по умолчанию

Метод GetUnspecifiedDefaultAttributes заполняет список ArrayList, заданный объектами XmlSchemaAttribute для всех атрибутов, значениями по умолчанию, которые ранее не были проверены с помощью метода ValidateAttribute в контексте элемента. Метод GetUnspecifiedDefaultAttributes следует вызывать после метода ValidateAttribute для каждого атрибута в контексте элемента. Метод GetUnspecifiedDefaultAttributes необходимо использовать для определения атрибутов по умолчанию, которые должны быть вставлены в проверяемый XML-документ.

Дополнительные сведения о методе GetUnspecifiedDefaultAttributes см. в справочной документации по классу XmlSchemaValidator.

Обработка событий проверки схемы

Предупреждения и ошибки схемы, встретившиеся во время проверки, обрабатываются событием ValidationEventHandler класса XmlSchemaValidator.

Предупреждения проверки схемы имеют значение XmlSeverityType с типом Warning, а ошибки проверки схемы имеют значение XmlSeverityType с типом Error. Если обработчик ValidationEventHandler не назначен, вызывается исключение XmlSchemaValidationException для всех ошибок проверки схемы со значением XmlSeverityType и типом Error. Однако исключение XmlSchemaValidationException не вызывается для предупреждений проверки схемы со значением XmlSeverityType и типом Warning.

Следующий пример обработчика ValidationEventHandler из введения получает предупреждения и ошибки проверки схемы, встретившиеся во время проверки.

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

Полный пример ValidationEventHandler см. во введении. Дополнительные сведения см. в справочной документации по классу XmlSchemaInfo.

Переход между состояниями XmlSchemaValidator

В классе XmlSchemaValidator объявляется переход между состояниями, определяющий последовательность и вхождение вызовов каждого метода, которые используются для проверки элементов, атрибутов и содержимого в информационном наборе XML.

В следующей таблице описан переход между состояниями класса XmlSchemaValidator, а также последовательность и вхождение вызовов методов, возможных в каждом состоянии.

State Transition
Проверить Initialize (ValidateAttribute | TopLevel*) EndValidation
TopLevel ValidateWhitespace | ValidateText | Элемент
Элемент ValidateElementValidateAttribute* (ValidateEndOfAttributes Содержимое*)? ValidateEndElement |

ValidateElement ValidateAttribute* SkipToEndElement |

ValidateElementValidateAttribute* ValidateEndOfAttributes Содержимого* SkipToEndElement |
Содержимое ValidateWhitespace | ValidateText | Элемент

Примечание.

Исключение InvalidOperationException вызывается всеми методами в приведенной выше таблице, если вызов метода выполняется в неверной последовательности в зависимости от текущего состояния объекта XmlSchemaValidator.

Приведенная выше таблица переходов между состояниями использует символы пунктуации для описания методов и других состояний, которые можно вызывать при переходе состояний класса XmlSchemaValidator. Используемые символы те же, что и в справочнике по XML-стандартам для определения типа документа (DTD).

В следующей таблице показано, как символы пунктуации из приведенной выше таблицы перехода состояний влияют на методы и другие состояния, которые можно вызывать при переходе состояний класса XmlSchemaValidator.

Символ Description
| Можно вызывать или метод, или состояние (перед чертой или после нее).
? Метод или состояние перед вопросительным знаком (?) являются необязательными, но их можно вызывать только один раз.
* Метод или состояние перед символом «звездочки» (*) являются необязательными. Их можно вызывать несколько раз.

Контекст проверки

Методы класса XmlSchemaValidator используются для проверки элементов, атрибутов и содержимого в информационном наборе XML, а также изменения контекста проверки объекта XmlSchemaValidator. Например, метод SkipToEndElement пропускает проверку содержимого текущего элемента и подготавливает объект XmlSchemaValidator для проверки в контексте родительского элемента. Это равнозначно пропуску проверки всех потомков текущего элемента и вызову метода ValidateEndElement.

Результаты выполнения методов GetExpectedParticles, GetExpectedAttributes и AddSchema класса XmlSchemaValidator зависят от текущего подвергаемого проверке контекста.

В следующей таблице приводятся результаты выполнения этих методов после вызова одного из методов класса XmlSchemaValidator для проверки элементов, атрибутов и содержимого в информационном наборе XML.

Способ GetExpectedParticles GetExpectedAttributes AddSchema
Initialize Если вызывается метод по умолчанию Initialize, метод GetExpectedParticles возвращает массив всех глобальных элементов.

Если перегруженный метод Initialize, принимающий в качестве параметра объект XmlSchemaObject, вызывается для инициализации частичной проверки элемента, метод GetExpectedParticles возвращает только элемент, для которого инициализируется объект XmlSchemaValidator.
Если вызывается метод по умолчанию Initialize, метод GetExpectedAttributes возвращает пустой массив.

Если перегруженный метод Initialize, принимающий в качестве параметра объект XmlSchemaObject, вызывается для инициализации частичной проверки атрибута, метод GetExpectedAttributes возвращает только атрибут, для которого инициализируется объект XmlSchemaValidator.
Добавляет схему к набору XmlSchemaSet объекта XmlSchemaValidator при отсутствии ошибок предварительной обработки.
ValidateElement Если контекстный элемент допустим, метод GetExpectedParticles возвращает последовательность элементов, ожидаемых в качестве потомков контекстного элемента.

Если контекстный элемент недопустим, GetExpectedParticles возвращает пустой массив.
Если контекстный элемент допустим, и не вызывался метод ValidateAttribute, метод GetExpectedAttributes возвращает список всех атрибутов, определенных в контекстном элементе.

Если некоторые атрибуты уже проверены, метод GetExpectedAttributes возвращает список оставшихся непроверенных атрибутов.

Если контекстный элемент недопустим, GetExpectedAttributes возвращает пустой массив.
То же, что выше.
ValidateAttribute Если контекстный атрибут является атрибутом верхнего уровня, GetExpectedParticles возвращает пустой массив.

В противном случае метод GetExpectedParticles возвращает последовательность элементов, ожидаемую в качестве первого дочернего элемента контекстного элемента.
Если контекстный атрибут является атрибутом верхнего уровня, GetExpectedAttributes возвращает пустой массив.

В противном случае метод GetExpectedAttributes возвращает список оставшихся непроверенных атрибутов.
То же, что выше.
GetUnspecifiedDefaultAttributes GetExpectedParticles возвращает последовательность элементов, ожидаемую в качестве первого дочернего элемента контекстного элемента. Метод GetExpectedAttributes возвращает список необходимых и необязательных атрибутов, оставшихся для проверки в контекстном элементе. То же, что выше.
ValidateEndOfAttributes GetExpectedParticles возвращает последовательность элементов, ожидаемую в качестве первого дочернего элемента контекстного элемента. Метод GetExpectedAttributes возвращает пустой массив. То же, что выше.
ValidateText Если содержимое контекстного элемента имеет тип Mixed, метод GetExpectedParticles возвращает последовательность элементов, ожидаемых в следующей позиции.

Если содержимое контекстного элемента имеет тип TextOnly или Empty, метод GetExpectedParticles возвращает пустой массив.

Если содержимое контекстного элемента имеет тип ElementOnly, метод GetExpectedParticles возвращает последовательность элементов, ожидаемых в следующей позиции, однако ошибка проверки уже произошла.
GetExpectedAttributes возвращает список атрибутов контекстного элемента, не подвергнутых проверке. То же, что выше.
ValidateWhitespace Если контекстный пробел является пробелом верхнего уровня, GetExpectedParticles возвращает пустой массив.

В противном случае поведение метода GetExpectedParticles аналогично ValidateText.
Если контекстный пробел является пробелом верхнего уровня, GetExpectedAttributes возвращает пустой массив.

В противном случае поведение метода GetExpectedAttributes аналогично ValidateText.
То же, что выше.
ValidateEndElement Метод GetExpectedParticles возвращает последовательность элементов, ожидаемых после контекстного элемента (возможных одноуровневых элементов). GetExpectedAttributes возвращает список атрибутов контекстного элемента, не подвергнутых проверке.

Если у контекстного элемента отсутствует родительский элемент, то метод GetExpectedAttributes возвращает пустой список (контекстный элемент является родительским для текущего элемента, в котором вызывается метод ValidateEndElement).
То же, что выше.
SkipToEndElement Эквивалентно ValidateEndElement. Эквивалентно ValidateEndElement. То же, что выше.
EndValidation Возвращает пустой массив. Возвращает пустой массив. То же, что выше.

Примечание.

Значения, возвращаемые различными свойствами класса XmlSchemaValidator, не изменяются при вызовах методов, описанных в приведенной выше таблице.

См. также