共用方式為


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>

使用 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 方法將不起作用。

AddSchema 方法的結果取決於要驗證的目前 XML 節點內容。 如需驗證內容的詳細資訊,請參閱本主題的<驗證內容>一節。

如需 AddSchema 方法的詳細資訊,請參閱 XmlSchemaValidator 類別參考文件。

驗證項目、屬性及內容

XmlSchemaValidator 類別提供幾種方法,可用於根據 XML 結構描述驗證 XML 資訊集中的項目、屬性及內容。 下表對每個方法進行說明。

方法 描述
ValidateElement 驗證目前內容中的項目名稱。
ValidateAttribute 驗證目前項目內容中的屬性,或根據做為參數傳遞給 XmlSchemaAttribute 方法的 Initialize 物件驗證屬性。
ValidateEndOfAttributes 驗證項目內容中的所有必要屬性是否均已存在,並準備 XmlSchemaValidator 物件以驗證項目的子內容。
ValidateText 驗證目前項目內容中是否允許文字,並且累積文件以驗證目前項目是否有簡單內容。
ValidateWhitespace 驗證目前項目內容中是否允許泛空白字元,並且累積泛空白字元以驗證目前項目是否有簡單內容。
ValidateEndElement 對於含簡單內容的項目,根據其資料型別驗證項目的文字內容是否有效;對於含複雜內容的項目,驗證目前項目的內容是否完整。
SkipToEndElement 略過目前項目內容的驗證,並準備 XmlSchemaValidator 物件,以驗證父項目內容 (Context) 中的內容 (Content)。
EndValidation 結束驗證,並且若已設定 ProcessIdentityConstraints 驗證選項,則檢查整個 XML 文件的識別條件約束。

注意

XmlSchemaValidator 類別具有定義的狀態轉換,可強制轉換對前一表格中說明之每個方法的呼叫順序及次數。 XmlSchemaValidator 類別的特定狀態轉換,在本主題的<XmlSchemaValidator 狀態轉換>一節中加以說明。

如需用來驗證 XML 資訊集中項目、屬性及內容之方法的範例,請參閱前一節中的範例。 如需這些方法的詳細資訊,請參閱 XmlSchemaValidator 類別參考文件。

使用 XmlValueGetter 驗證內容

XmlValueGetterdelegate 可用於傳遞屬性、文字或泛空白字元節點的值,成為 Common Language Runtime (CLR) 型別,該型別與它們的 XML 結構描述定義語言 (XSD) 型別相容。 如果屬性、文字或泛空白字元節點的 CLR 值已經可用,則 XmlValueGetterdelegate 就很有用,且避免將它轉換為 string,然後重新剖析以進行驗證的成本。

ValidateAttributeValidateTextValidateWhitespace 方法是多載方法,並可接受屬性、文字及泛空白字元節點的值做為 stringXmlValueGetterdelegate

XmlSchemaValidator 類別的下列方法接受 XmlValueGetterdelegate 做為參數。

以下 XmlValueGetterdelegate 範例取自簡介中的 XmlSchemaValidator 類別範例。 XmlValueGetterdelegate 會將屬性的值做為 DateTime 物件傳回。 為驗證 DateTime 傳回的 XmlValueGetter 物件,XmlSchemaValidator 物件先將其轉換成屬性資料型別 ValueType (ValueType 是 XSD 型別的預設 CLR 對應),然後檢查已轉換值的 Facet。

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 類別參考文件。

Post-Schema-Validation-Information

XmlSchemaInfo 類別表示 XmlSchemaValidator 類別所驗證之 XML 節點的部分後結構描述驗證資訊。 XmlSchemaValidator 類別的各種方法均可以接受 XmlSchemaInfo 物件做為選擇性 (null) out 參數。

成功驗證後,會以驗證的結果設定 XmlSchemaInfo 物件的屬性。 例如,使用 ValidateAttribute 方法成功驗證屬性後,會以驗證的結果設定 XmlSchemaInfo 物件的 (如果已指定) SchemaAttributeSchemaTypeMemberTypeValidity 屬性。

下列 XmlSchemaValidator 類別方法接受 XmlSchemaInfo 物件做為輸出參數。

如需 XmlSchemaInfo 類別的完整範例,請參閱簡介中的範例。 如需 XmlSchemaInfo 類別的詳細資訊,請參閱 XmlSchemaInfo 類別參考文件。

擷取預期物件、屬性及未指定的預設屬性

XmlSchemaValidator 類別提供 GetExpectedAttributesGetExpectedParticlesGetUnspecifiedDefaultAttributes 方法,以擷取目前驗證內容中的預期物件、屬性及未指定的預設屬性。

擷取預期物件

GetExpectedParticles 方法會傳回含目前項目內容中預期物件 (Particle) 的 XmlSchemaParticle 物件 (Object) 陣列。 可由 GetExpectedParticles 方法傳回的有效物件為 XmlSchemaElementXmlSchemaAny 類別的執行個體。

當內容模型的複合器為 xs:sequence 時,只傳回序列中的下一個物件。 如果內容模型的複合器為 xs:allxs:choice,則傳回目前項目內容中所有後續的有效物件。

注意

如果在呼叫 GetExpectedParticles 方法後立即呼叫Initialize 方法,則 GetExpectedParticles 方法會傳回所有的全域項目。

例如,在隨後的 XML 結構描述定義語言 (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>

注意

GetExpectedParticlesGetExpectedAttributesAddSchema 類別之 XmlSchemaValidator 方法的結果,取決於要驗證的目前內容。 如需詳細資訊,請參閱本主題的<驗證內容>一節。

如需 GetExpectedParticles 方法的範例,請參閱簡介中的範例。 如需 GetExpectedParticles 方法的詳細資訊,請參閱 XmlSchemaValidator 類別參考文件。

擷取預期屬性

GetExpectedAttributes 方法會傳回含目前項目內容中預期屬性的 XmlSchemaAttribute 物件陣列。

例如,在簡介內的範例中,GetExpectedAttributes 方法用於擷取 book 項目的所有屬性。

如果在呼叫 GetExpectedAttributes 方法之後立即呼叫 ValidateElement 方法,則會傳回 XML 文件中出現的所有屬性。 但是,如果在對 GetExpectedAttributes 方法進行一或多次呼叫之後呼叫 ValidateAttribute 方法,則會傳回目前項目之尚未驗證的屬性。

注意

GetExpectedParticlesGetExpectedAttributesAddSchema 類別之 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 類別的狀態轉換,以及在每個狀態下可進行之方法呼叫的順序及次數。

州/省 轉換
Validate Initialize (ValidateAttribute | TopLevel*) EndValidation
TopLevel ValidateWhitespace | ValidateText | Element
元素 ValidateElement ValidateAttribute* (ValidateEndOfAttributes Content*)? ValidateEndElement |

ValidateElement ValidateAttribute* SkipToEndElement |

ValidateElement ValidateAttribute* ValidateEndOfAttributes Content* SkipToEndElement |
Content ValidateWhitespace | ValidateText | Element

注意

根據 InvalidOperationException 物件的目前狀態,如果呼叫上表中的每個方法的順序不正確,則它們會擲回 XmlSchemaValidator

以上狀態轉換表會使用標點符號,說明可針對 XmlSchemaValidator 類別之狀態轉換的每個狀態呼叫的方法及其他狀態。 所使用的符號與在物件型別定義 (DTD) 之 XML 標準參考中找到的符號相同。

下表說明在以上狀態轉換表中找到的標點符號,如何影響針對 XmlSchemaValidator 類別之狀態轉換中每個狀態呼叫的方法及其他狀態。

符號 描述
| 可呼叫方法或狀態 (垂直線前後的項目)。
? 問號之前的方法或狀態是選擇性的,但如果呼叫它,則只能呼叫一次。
* * 符號之前的方法或狀態是選擇性的,可對其呼叫多次。

驗證內容

用於驗證 XML 資訊集中項目、屬性及內容之 XmlSchemaValidator 類別的方法,可變更 XmlSchemaValidator 物件的驗證內容。 例如,SkipToEndElement 方法會略過目前項目內容的驗證,並準備 XmlSchemaValidator 物件以驗證父項目內容 (Context) 中的內容 (Content);這相當於略過目前項目之所有項目子系的驗證,並呼叫 ValidateEndElement 方法。

GetExpectedParticlesGetExpectedAttributesAddSchema 類別之 XmlSchemaValidator 方法的結果,取決於要驗證的目前內容。

下表說明在呼叫用於驗證 XML 資訊集中項目、屬性及內容之 XmlSchemaValidator 類別的其中一個方法之後,呼叫這些方法的結果。

方法 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 如果內容項目的 contentType 為 Mixed,則 GetExpectedParticles 會傳回下一個位置中預期的項目序列。

如果內容項目的 contentType 為 TextOnly 或 Empty,則 GetExpectedParticles 會傳回空陣列。

如果內容項目的 contentType 為 ElementOnly,則 GetExpectedParticles 會傳回下一個位置中預期的、但已發生驗證錯誤的項目序列。
GetExpectedAttributes 會傳回未驗證之屬性的內容項目清單。 同上。
ValidateWhitespace 如果內容泛空白字元是最上層泛空白字元,則 GetExpectedParticles 會傳回空陣列。

否則,GetExpectedParticles 方法的行為與 ValidateText 中的相同。
如果內容泛空白字元是最上層泛空白字元,則 GetExpectedAttributes 會傳回空陣列。

否則,GetExpectedAttributes 方法的行為與 ValidateText 中的相同。
同上。
ValidateEndElement GetExpectedParticles 會傳回預期位於內容項目之後 (可能為同層級) 的項目序列。 GetExpectedAttributes 會傳回未驗證之屬性的內容項目清單。

如果內容項目沒有父代,則 GetExpectedAttributes 會傳回空清單 (內容項目是已呼叫 ValidateEndElement 之目前項目的父代)。
同上。
SkipToEndElement ValidateEndElement 相同。 ValidateEndElement 相同。 同上。
EndValidation 傳回空陣列。 傳回空陣列。 同上。

注意

呼叫上表中的任何方法,均不會改變 XmlSchemaValidator 類別之各種屬性所傳回的值。

另請參閱