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: '{nextElement.Name}'");

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        static object dateTimeGetterHandle()
        {
            return dateTimeGetterContent;
        }

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

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

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

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

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

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

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

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

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

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

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

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

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


Namespace Microsoft.Samples.Xml.Schema

    Class XmlSchemaValidatorExamples

        Shared Sub Main()

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

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

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

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

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

            ' Initialize the XmlSchemaValidator object.
            validator.Initialize()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                End If

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

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

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

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

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

            ' Close the XmlReader object.
            reader.Close()

        End Sub

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

        Shared Function dateTimeGetterHandle() As Object

            Return dateTimeGetterContent

        End Function

        Shared Function dateTimeGetter(ByVal dateTime As DateTime) As XmlValueGetter

            dateTimeGetterContent = dateTime
            Return New XmlValueGetter(AddressOf dateTimeGetterHandle)

        End Function

        Shared Sub DisplaySchemaInfo()

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

        End Sub

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

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

        End Sub

    End Class

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

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

    End Class

    Public Class BookType

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

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

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

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

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

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

    End Class

    Public Class BookAuthor

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

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

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

    End Class

End Namespace

该示例将 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>

使用 XmlSchemaValidator 验证 XML 数据

要开始验证 XML 信息集,需要先使用XmlSchemaValidator构造函数初始化XmlSchemaValidator类的新实例。

XmlSchemaValidator 构造函数使用 XmlNameTableXmlSchemaSetXmlNamespaceManager 对象作为参数,同时也将 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 将不执行任何作。

正在验证的当前 XML 节点上下文决定了方法 AddSchema 的结果。 有关验证上下文的详细信息,请参阅本主题的“验证上下文”部分。

有关 AddSchema 方法的详细信息,请参阅 XmlSchemaValidator 类参考文档。

验证元素、属性和内容

XmlSchemaValidator 类提供了多种方法,用于针对 XML 架构验证 XML 信息集中的元素、属性和内容。 下表描述了其中每个方法。

方法 DESCRIPTION
ValidateElement 验证当前上下文中的元素名称。
ValidateAttribute 在当前元素上下文中验证属性,或针对作为参数传递给 XmlSchemaAttribute 方法的 Initialize 对象验证属性。
ValidateEndOfAttributes 验证元素上下文中的所有必需属性是否存在,并准备 XmlSchemaValidator 对象以验证元素的子内容。
ValidateText 验证当前元素上下文中是否允许文本,并累积文本以验证当前元素是否具有简单内容。
ValidateWhitespace 验证当前元素上下文中是否允许空格,并累积空白以验证当前元素是否具有简单内容。
ValidateEndElement 验证具有简单内容的元素的文本内容是否根据其数据类型有效,并验证具有复杂内容的当前元素的内容是否完整。
SkipToEndElement 跳过当前元素内容的验证,并准备 XmlSchemaValidator 对象以验证父元素上下文中的内容。
EndValidation 如果 ProcessIdentityConstraints 设置了验证选项,则结束验证并检查整个 XML 文档的标识约束。

注释

XmlSchemaValidator 类具有定义的状态转换,该转换强制执行对上表中所述每个方法的调用的顺序和次数。 XmlSchemaValidator 类特定的状态转换在本主题的“XmlSchemaValidator 状态转换”一节中介绍。

有关用于验证 XML 信息集中的元素、属性和内容的方法示例,请参阅上一节中的示例。 有关这些方法的详细信息,请参阅 XmlSchemaValidator 类参考文档。

使用 XmlValueGetter 验证内容

XmlValueGetter delegate可用于将属性、文本或空白节点的值作为与属性、文本或空白节点的 XML 架构定义语言(XSD)类型兼容的公共语言运行时(CLR)类型传递。 当属性、文本或空白节点的 CLR 值已可用时,XmlValueGetterdelegate非常有用,这避免了将其转换为string然后重新解析以进行验证的成本。

ValidateAttributeValidateTextValidateWhitespace 方法是重载方法,使用属性、文本或空白节点的值作为 stringXmlValueGetterdelegate

类的 XmlSchemaValidator 以下方法接受 XmlValueGetterdelegate 作为参数。

下面是从简介中的 XmlValueGetter 类示例获取的示例 delegateXmlSchemaValidatorXmlValueGetter delegateDateTime 对象的形式返回属性的值。 要验证 DateTime 返回的此 XmlValueGetter 对象,XmlSchemaValidator 对象先将其转换为属性数据类型的 ValueType(ValueType 是该 XSD 类型默认的 CLR 映射),然后检查转换后的值的各个方面。

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 的更多信息,请参阅 XmlValueGetterXmlSchemaValidator 类的参考文档。

后架构验证信息

XmlSchemaInfo 类表示通过 XmlSchemaValidator 类验证的 XML 节点的一些后架构验证信息。 类的各种方法 XmlSchemaValidator 接受对象 XmlSchemaInfo 作为可选的 (nullout 参数。

成功验证后,使用 XmlSchemaInfo 验证结果设置对象的属性。 例如,通过ValidateAttribute方法成功验证属性后,如果指定,则使用验证结果设置XmlSchemaInfo对象的SchemaAttributeSchemaTypeMemberTypeValidity属性。

以下 XmlSchemaValidator 类方法接受对象 XmlSchemaInfo 作为 out 参数。

请参阅简介中的示例,以了解XmlSchemaInfo类的完整示例。 有关该 XmlSchemaInfo 类的详细信息,请参阅 XmlSchemaInfo 类参考文档。

检索预期的粒子、属性和未指定的默认属性

XmlSchemaValidator类提供GetExpectedAttributesGetExpectedParticlesGetUnspecifiedDefaultAttributes方法,用于在当前验证上下文中检索预期的粒子、属性和未指定的默认属性。

检索预计的粒子

该方法 GetExpectedParticles 返回包含当前元素上下文中预期粒子的对象数组 XmlSchemaParticleGetExpectedParticles 方法可以返回的有效粒子是 XmlSchemaElementXmlSchemaAny 类的实例。

当内容模型的合成器为一个 xs:sequence时,只返回序列中的下一个粒子。 如果内容模型的合成器为 xs:allxs:choice,则在当前元素上下文中可遵循的所有有效粒子将被给出。

注释

GetExpectedParticles如果在调用Initialize该方法后立即调用该方法,该方法GetExpectedParticles将返回所有全局元素。

例如,在验证 book 元素后,在 XML 架构定义语言(XSD)架构和 XML 文档中,元素 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类的GetExpectedAttributesAddSchemaXmlSchemaValidator方法的结果。 有关详细信息,请参阅本主题的“验证上下文”部分。

要查看方法 GetExpectedParticles 的示例,请参阅该简介中的示例。 有关 GetExpectedParticles 方法的详细信息,请参阅 XmlSchemaValidator 类参考文档。

检索预计的属性

该方法 GetExpectedAttributes 返回包含当前元素上下文中预期属性的对象数组 XmlSchemaAttribute

例如,在简介中的示例中, GetExpectedAttributes 该方法用于检索元素的所有属性 book

如果GetExpectedAttributes方法之后立即调用ValidateElement方法,将返回 XML 文档中可能出现的所有属性。 但是,如果在对GetExpectedAttributes方法进行一个或多个调用后再调用ValidateAttribute方法,就会返回当前元素中尚未验证的属性。

注释

正在验证的当前上下文决定了GetExpectedParticles类的GetExpectedAttributesAddSchemaXmlSchemaValidator方法的结果。 有关详细信息,请参阅本主题的“验证上下文”部分。

要查看方法 GetExpectedAttributes 的示例,请参阅该简介中的示例。 有关 GetExpectedAttributes 方法的详细信息,请参阅 XmlSchemaValidator 类参考文档。

检索未指定的默认属性

GetUnspecifiedDefaultAttributes 方法使用元素上下文中以前尚未使用 ArrayList 方法进行验证的默认值填充使用任何属性的 XmlSchemaAttribute 对象指定的 ValidateAttribute。 在元素上下文中对每个属性调用GetUnspecifiedDefaultAttributes方法之后,应调用ValidateAttribute方法。 GetUnspecifiedDefaultAttributes该方法应用于确定要插入到要验证的 XML 文档中的默认属性。

有关 GetUnspecifiedDefaultAttributes 方法的详细信息,请参阅 XmlSchemaValidator 类参考文档。

处理架构验证事件

验证期间遇到的架构验证警告和错误由 ValidationEventHandler 类的事件 XmlSchemaValidator 处理。

架构验证警告具有值XmlSeverityTypeWarning,架构验证错误的值XmlSeverityTypeError. 如果尚未分配任何 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类的状态转换,以及每个状态中可进行的方法调用的顺序和频率。

国家 过渡
驗證 InitializeValidateAttribute |TopLevel*) EndValidation
TopLevel ValidateWhitespace | ValidateText |元素
元素 ValidateElement ValidateAttribute* (ValidateEndOfAttributes 内容*)? ValidateEndElement |

ValidateElement ValidateAttribute * SkipToEndElement |

ValidateElement ValidateAttribute * ValidateEndOfAttributes 内容* SkipToEndElement |
内容 ValidateWhitespace | ValidateText |元素

注释

如果调用方法的顺序不符合 InvalidOperationException 对象的当前状态,上表中的每种方法将引发 XmlSchemaValidator

上面的状态转换表使用标点符号来描述可为类状态转换 XmlSchemaValidator 的每个状态调用的方法和其他状态。 使用的符号与在文档类型定义(DTD)的 XML 标准参考中找到的符号相同。

下表介绍了在上述状态转换表中找到的标点符号如何影响可针对类状态转换 XmlSchemaValidator 中每个状态调用的方法和其他状态。

符号 DESCRIPTION
| 可以调用(竖线之前或竖线之后的)方法或状态。
? 问号前面的方法或状态是可选的,但如果它被调用,则只能调用一次。
* * 符号前面的方法或状态是可选的,可以多次调用。

验证上下文

用于验证 XML 信息集中的元素、属性和内容的 XmlSchemaValidator 类的方法,会更改 XmlSchemaValidator 对象的验证上下文。 例如,该方法 SkipToEndElement 跳过当前元素内容的验证,并准备 XmlSchemaValidator 对象以验证父元素上下文中的内容;它等效于跳过当前元素的所有子级的验证,然后调用 ValidateEndElement 该方法。

正在验证的当前上下文决定了GetExpectedParticles类的GetExpectedAttributesAddSchemaXmlSchemaValidator方法的结果。

下表介绍在调用 XmlSchemaValidator 类中的一个用于验证 XML 信息集中的元素、属性和内容的方法之后调用这些方法的结果。

方法 GetExpectedParticles GetExpectedAttributes AddSchema
Initialize 如果调用默认 Initialize 方法, GetExpectedParticles 则返回包含所有全局元素的数组。

如果调用以 Initialize 为参数的重载 XmlSchemaObject 方法来初始化元素的部分验证,GetExpectedParticles 只返回该对象初始化到的 XmlSchemaValidator 元素。
如果调用默认 Initialize 方法, GetExpectedAttributes 则返回一个空数组。

如果调用使用 Initialize 作为参数的重载 XmlSchemaObject 方法来初始化属性的部分验证,GetExpectedAttributes 将只返回 XmlSchemaValidator 对象初始化所针对的属性。
如果XmlSchemaSetXmlSchemaValidator对象没有预处理错误,则将架构添加到该对象中。
ValidateElement 如果上下文元素有效,GetExpectedParticles 则返回该上下文元素预期的子元素序列。

如果上下文元素无效, GetExpectedParticles 则返回一个空数组。
如果上下文元素有效,并且以前ValidateAttribute没有调用,GetExpectedAttributes则返回上下文元素上定义的所有属性的列表。

如果某些属性已验证, GetExpectedAttributes 则返回要验证的剩余属性的列表。

如果上下文元素无效, GetExpectedAttributes 则返回一个空数组。
同上。
ValidateAttribute 如果上下文属性是顶级属性, GetExpectedParticles 则返回一个空数组。

否则 GetExpectedParticles 返回作为上下文元素的第一个子元素的预期元素序列。
如果上下文属性是顶级属性, GetExpectedAttributes 则返回一个空数组。

否则 GetExpectedAttributes 返回要验证的剩余属性的列表。
同上。
GetUnspecifiedDefaultAttributes GetExpectedParticles 返回作为上下文元素的第一个子元素的预期元素序列。 GetExpectedAttributes 返回尚未为上下文元素验证的必需属性和可选属性的列表。 同上。
ValidateEndOfAttributes GetExpectedParticles 返回作为上下文元素的第一个子元素的预期元素序列。 GetExpectedAttributes 返回空数组。 同上。
ValidateText 如果上下文元素的 contentType 为 Mixed, GetExpectedParticles 则返回下一位置预期的元素序列。

如果上下文元素的 contentType 为 TextOnly 或 Empty, GetExpectedParticles 则返回空数组。

如果上下文元素的 contentType 为 ElementOnly, GetExpectedParticles 则返回下一位置中预期的元素序列,但已发生验证错误。
GetExpectedAttributes 返回未验证的上下文元素的属性列表。 同上。
ValidateWhitespace 如果上下文空白是顶级空白, GetExpectedParticles 则返回一个空数组。

否则, GetExpectedParticles 该方法的行为与 in ValidateText相同。
如果上下文空白是顶级空白, GetExpectedAttributes 则返回一个空数组。

否则, GetExpectedAttributes 该方法的行为与 in ValidateText相同。
同上。
ValidateEndElement GetExpectedParticles 返回上下文元素(可能的同级)之后预期的元素序列。 GetExpectedAttributes 返回未验证的上下文元素的属性列表。

如果上下文元素没有父元素,则 GetExpectedAttributes 返回一个空列表(上下文元素是调用的 ValidateEndElement 当前元素的父元素)。
同上。
SkipToEndElement ValidateEndElement 相同。 ValidateEndElement 相同。 同上。
EndValidation 返回一个空数组。 返回一个空数组。 同上。

注释

通过调用上表中的任何方法,类的各种属性 XmlSchemaValidator 返回的值不会改变。

另请参阅