共用方式為


使用 XPathNavigator 進行結構描述驗證

更新: November 2007

您可以使用 XmlDocument 類別,透過兩種方式驗證 XmlDocument 物件中包含的 XML 內容。第一種方式是使用驗證 XmlReader 物件來驗證 XML 內容,第二種方式是使用 XmlDocument 類別的 Validate 方法。此外,您也可以使用 XPathDocument 類別,執行 XML 內容的唯讀驗證。

驗證 XML 資料

依預設,XmlDocument 類別不會使用 DTD 或 XML 結構描述定義語言 (XSD) 結構描述驗證,來驗證 XML 文件。它只會驗證 XML 文件的格式是否正確。

第一種驗證 XML 文件的方式是使用驗證 XmlReader 物件,在將文件載入至 XmlDocument 物件時進行驗證。第二種方式是使用 XmlDocument 類別的 Validate 方法,驗證先前不具型別的 XML 文件。在這兩種情況下,都可以使用 XmlDocument 類別的 Validate 方法,重新驗證已驗證 XML 文件的變更。

載入文件時進行驗證

驗證 XmlReader 物件可透過將 XmlReaderSettings 物件傳遞至 XmlReader 類別的 Create 方法 (其將 XmlReaderSettings 物件視為參數) 來建立。做為參數傳遞之 XmlReaderSettings 物件具有設為 SchemaValidationType 屬性,並且 XmlDocument 物件中包含之 XML 文件的 XML 結構描述會加入其 Schemas 屬性中。然後,驗證 XmlReader 物件即可用來建立 XmlDocument 物件。

下列範例透過使用驗證 XmlReader 物件建立 XmlDocument 物件,以在將 contosoBooks.xml 檔案載入至 XmlDocument 物件時對其進行驗證。因為根據該 XML 文件的結構描述的內容,它是有效的,所以不會產生結構描述驗證錯誤或警告。

Imports System
Imports System.Xml
Imports System.Xml.Schema
Imports System.Xml.XPath
 
Class ValidatingReaderExample

    Shared Sub Main(ByVal args() As String)

        Try
            Dim settings As XmlReaderSettings = New XmlReaderSettings()
            settings.Schemas.Add("https://www.contoso.com/books", "contosoBooks.xsd")
            settings.ValidationType = ValidationType.Schema

            Dim reader As XmlReader = XmlReader.Create("contosoBooks.xml", settings)

            Dim document As XmlDocument = New XmlDocument()
            document.Load(reader)
            Dim navigator As XPathNavigator = document.CreateNavigator()

        Catch e As Exception
            Console.WriteLine("ValidatingReaderExample.Exception: {0}", e.Message)
        End Try

    End Sub

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

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

    End Sub

End Class
using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.XPath;

class ValidatingReaderExample
{
    static void Main(string[] args)
    {
        try
        {
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.Schemas.Add("https://www.contoso.com/books", "contosoBooks.xsd");
            settings.ValidationType = ValidationType.Schema;

            XmlReader reader = XmlReader.Create("contosoBooks.xml", settings);

            XmlDocument document = new XmlDocument();
            document.Load(reader);
            XPathNavigator navigator = document.CreateNavigator();
        }
        catch (Exception e)
        {
            Console.WriteLine("ValidatingReaderExample.Exception: {0}", e.Message);
        }
    }

    static void SchemaValidationHandler(object sender, ValidationEventArgs e)
    {
        switch (e.Severity)
        {
            case XmlSeverityType.Error:
                Console.WriteLine("Schema Validation Error: {0}", e.Message);
                break;
            case XmlSeverityType.Warning:
                Console.WriteLine("Schema Validation Warning: {0}", e.Message);
                break;
        }
    }
}

範例將採用 contosoBooks.xml 檔案做為輸入。

<bookstore xmlns="https://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="https://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>

在上述範例中,如果有任何屬性或項目型別不符合驗證結構描述內指定的對應型別,則在呼叫 Load 時將會擲回 XmlSchemaValidationException。如果在驗證 XmlReader 上設定了 ValidationEventHandler,則每當遇到無效的型別時,都將呼叫 ValidationEventHandler

XPathNavigator 存取將 TypedValue 設定為 invalid 的屬性或項目時,將會擲回 XmlSchemaException

Validity 屬性可用來決定當使用 XPathNavigator 存取屬性或項目時,個別的屬性或項目是否有效。

注意事項:

當 XML 文件載入至具有可定義預設值之關聯結構描述的 XmlDocument 物件時,XmlDocument 會處理這些預設值,就好像它們是出現在 XML 文件中。這表示針對結構描述中預設的項目,即使在 XML 文件中將其做為空白項目寫入,IsEmptyElement 屬性永遠會傳回 false。

使用驗證方法驗證文件

XmlDocument 類別的 Validate 方法會根據 XmlDocument 物件之 Schemas 屬性中指定的結構描述,驗證 XmlDocument 物件中包含的 XML 文件,並執行資訊集增加。其結果是以具型別文件取代 XmlDocument 物件中先前不具型別的 XML 文件。

XmlDocument 物件會使用做為參數傳遞至 Validate 方法的 ValidationEventHandler 委派,報告結構描述驗證錯誤及警告。

下列範例根據 XmlDocument 物件之 Schemas 屬性中包含的 contosoBooks.xsd 結構描述,驗證 XmlDocument 物件中包含的 contosoBooks.xml 檔案。

Imports System
Imports System.Xml
Imports System.Xml.Schema
Imports System.Xml.XPath
 
Class ValidateExample

    Shared Sub Main(ByVal args() As String)

        Dim document As XmlDocument = New XmlDocument()
        document.Load("contosoBooks.xml")
        Dim navigator As XPathNavigator = document.CreateNavigator()

        document.Schemas.Add("https://www.contoso.com/books", "contosoBooks.xsd")
        Dim validation As ValidationEventHandler = New ValidationEventHandler(AddressOf SchemaValidationHandler)

        document.Validate(validation)

    End Sub

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

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

    End Sub

End Class
using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.XPath;

class ValidateExample
{
    static void Main(string[] args)
    {
        XmlDocument document = new XmlDocument();
        document.Load("contosoBooks.xml");
        XPathNavigator navigator = document.CreateNavigator();

        document.Schemas.Add("https://www.contoso.com/books", "contosoBooks.xsd");
        ValidationEventHandler validation = new ValidationEventHandler(SchemaValidationHandler);

        document.Validate(validation);
    }

    static void SchemaValidationHandler(object sender, ValidationEventArgs e)
    {
        switch (e.Severity)
        {
            case XmlSeverityType.Error:
                Console.WriteLine("Schema Validation Error: {0}", e.Message);
                break;
            case XmlSeverityType.Warning:
                Console.WriteLine("Schema Validation Warning: {0}", e.Message);
                break;
        }
    }
}

範例將採用 contosoBooks.xml 檔案做為輸入。

<bookstore xmlns="https://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="https://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 文件進行修改之後,您可以使用 XmlDocument 類別的 Validate 方法,根據 XML 文件的結構描述驗證修改。

下列範例透過使用驗證 XmlReader 物件建立 XmlDocument 物件,以在將 contosoBooks.xml 檔案載入至 XmlDocument 物件時對其進行驗證。XML 文件在載入時順利完成驗證,沒有產生任何結構描述驗證錯誤或警告。然後,根據 contosoBooks.xsd 結構描述,本範例對 XML 文件進行兩處無效的修改。第一處修改是插入導致結構描述驗證錯誤的無效項目子系,而第二處修改則是將具型別節點的值,設為對於節點型別而言無效的值,從而導致例外狀況。

Imports System
Imports System.Xml
Imports System.Xml.Schema
Imports System.Xml.XPath
 
Class ValidatingReaderExample

    Shared Sub Main(ByVal args() As String)

        Try
            Dim settings As XmlReaderSettings = New XmlReaderSettings()
            settings.Schemas.Add("https://www.contoso.com/books", "contosoBooks.xsd")
            settings.ValidationType = ValidationType.Schema

            Dim reader As XmlReader = XmlReader.Create("contosoBooks.xml", settings)

            Dim document As XmlDocument = New XmlDocument()
            document.Load(reader)
            Dim navigator As XPathNavigator = document.CreateNavigator()

            Dim validation As ValidationEventHandler = New ValidationEventHandler(AddressOf SchemaValidationHandler)

            navigator.MoveToChild("bookstore", "https://www.contoso.com/books")
            navigator.MoveToChild("book", "https://www.contoso.com/books")
            navigator.MoveToChild("author", "https://www.contoso.com/books")

            navigator.AppendChild("<title>Book Title</title>")

            document.Validate(validation)

            navigator.MoveToParent()
            navigator.MoveToChild("price", "https://www.contoso.com/books")
            navigator.SetTypedValue(DateTime.Now)
        Catch e As Exception
            Console.WriteLine("ValidatingReaderExample.Exception: {0}", e.Message)
        End Try

    End Sub

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

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

    End Sub

End Class
using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.XPath;

class ValidatingReaderExample
{
    static void Main(string[] args)
    {
        try
        {
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.Schemas.Add("https://www.contoso.com/books", "contosoBooks.xsd");
            settings.ValidationType = ValidationType.Schema;

            XmlReader reader = XmlReader.Create("contosoBooks.xml", settings);

            XmlDocument document = new XmlDocument();
            document.Load(reader);
            XPathNavigator navigator = document.CreateNavigator();

            ValidationEventHandler validation = new ValidationEventHandler(SchemaValidationHandler);

            navigator.MoveToChild("bookstore", "https://www.contoso.com/books");
            navigator.MoveToChild("book", "https://www.contoso.com/books");
            navigator.MoveToChild("author", "https://www.contoso.com/books");

            navigator.AppendChild("<title>Book Title</title>");
            
            document.Validate(validation);

            navigator.MoveToParent();
            navigator.MoveToChild("price", "https://www.contoso.com/books");
            navigator.SetTypedValue(DateTime.Now);
        }
        catch (Exception e)
        {
            Console.WriteLine("ValidatingReaderExample.Exception: {0}", e.Message);
        }
    }

    static void SchemaValidationHandler(object sender, ValidationEventArgs e)
    {
        switch (e.Severity)
        {
            case XmlSeverityType.Error:
                Console.WriteLine("Schema Validation Error: {0}", e.Message);
                break;
            case XmlSeverityType.Warning:
                Console.WriteLine("Schema Validation Warning: {0}", e.Message);
                break;
        }
    }
}

範例將採用 contosoBooks.xml 檔案做為輸入。

<bookstore xmlns="https://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="https://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>

在上述範例中,對 XmlDocument 物件中包含的 XML 文件進行兩處修改。在載入 XML 文件時,所發生的任何結構描述驗證錯誤都會由驗證事件處理常式方法進行處理,並寫入主控台。

在此範例中,載入 XML 文件後發生了驗證錯誤,並且會透過 XmlDocument 類別的 Validate 方法來發現錯誤。

使用 XPathNavigator 類別的 SetTypedValue 方法進行的修改導致 InvalidCastException,因為根據節點的結構描述型別,新值是無效的。

如需使用 SetTypedValue 方法修改值的詳細資訊,請參閱 使用 XPathNavigator 修改 XML 資料 主題。

唯讀驗證

XPathDocument 類別是 XML 文件之唯讀的記憶體中表示。XPathDocument 類別及 XmlDocument 類別都可建立 XPathNavigator 物件,以巡覽及編輯 XML 文件。因為 XPathDocument 類別是唯讀類別,所以從 XPathDocument 物件傳回的 XPathNavigator 物件無法編輯 XPathDocument 物件中包含的 XML 文件。

在驗證時,您可以如本主題中先前所述,使用與驗證 XmlReader 物件建立 XmlDocument 物件相同的方式,建立 XPathDocument 物件。XPathDocument 物件會在載入 XML 文件時對其進行驗證,但是因為無法編輯 XPathDocument 物件中的 XML 資料,所以您無法重新驗證 XML 文件。

如需唯讀及可編輯 XPathNavigator 物件的詳細資訊,請參閱 使用 XPathDocument 及 XmlDocument 讀取 XML 資料 主題。

請參閱

概念

使用 XPath 資料模型處理 XML 資料

使用 XPathDocument 及 XmlDocument 讀取 XML 資料

使用 XPathNavigator 選取、評估及比對 XML 資料

使用 XPathNavigator 存取 XML 資料

使用 XPathNavigator 編輯 XML 資料

參考

XmlDocument

XPathDocument

XPathNavigator