Share via


Schema-Validierung mithilfe von XPathNavigator

Mithilfe der XmlDocument-Klasse haben Sie zwei Möglichkeiten, den XML-Inhalt eines XmlDocument-Objekts zu validieren. Die erste Möglichkeit zum Validieren von XML-Inhalt besteht darin, ein validierendes XmlReader-Objekt zu verwenden, und die zweite Möglichkeit besteht in der Verwendung der Validate-Methode der XmlDocument-Klasse. Mithilfe der XPathDocument-Klasse können Sie eine schreibgeschützte Validierung von XML-Inhalt durchführen.

Validieren von XML-Daten

In der Standardeinstellung validiert die XmlDocument-Klasse ein XML-Dokument nicht mithilfe der DTD- oder XSD-Schemavalidierung (XML Schema Definition Language). Es wird nur überprüft, ob das XML-Dokument wohlgeformt ist.

Die erste Möglichkeit zum Validieren eines XML-Dokuments ist das Validieren des Dokuments mithilfe eines validierenden XmlDocument-Objekts beim Laden in ein XmlReader-Objekt. Die zweite Möglichkeit ist das Validieren eines zuvor nicht typisierten XML-Dokuments mithilfe der Validate-Methode der XmlDocument-Klasse. In beiden Fällen können Änderungen des validierten XML-Dokuments mithilfe der Validate-Methode der XmlDocument-Klasse erneut validiert werden.

Validieren eines Dokuments während des Ladevorgangs

Ein validierendes XmlReader-Objekt wird durch das Übergeben eines XmlReaderSettings-Objekts an die Create-Methode der XmlReader-Klasse erstellt, die ein XmlReaderSettings-Objekt als Parameter annimmt. Das als Parameter übergebene XmlReaderSettings-Objekt verfügt über eine ValidationType-Eigenschaft, die auf Schema festgelegt ist, und über ein XML-Schema für das XML-Dokument, das in dem dessen XmlDocument-Eigenschaft hinzugefügten Schemas-Objekt enthalten ist. Das validierende XmlReader-Objekt wird dann zum Erstellen des XmlDocument-Objekts verwendet.

Im folgenden Beispiel wird die contosoBooks.xml-Datei beim Laden in das XmlDocument-Objekt validiert, indem das XmlDocument-Objekt mithilfe eines validierenden XmlReader-Objekts erstellt wird. Da das XML-Dokument entsprechend seines Schemas gültig ist, werden keine Schemavalidierungsfehler oder -warnungen generiert.

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("http://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("http://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;  
        }  
    }  
}  

In diesem Beispiel wird die Datei contosoBooks.xml als Eingabe verwendet.

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

In diesem Beispiel wird auch contosoBooks.xsd als Eingabe verwendet.

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

Im Beispiel oben wird eine XmlSchemaValidationException ausgelöst, wenn Load aufgerufen wird, falls ein Attribut oder Elementtyp nicht mit dem im Validierungsschema angegebenen zugehörigen Typ übereinstimmt. Wenn für den validierenden ValidationEventHandler ein XmlReader festgelegt wurde, wird der ValidationEventHandler aufgerufen, sobald ein ungültiger Typ gefunden wird.

Greift der XmlSchemaException auf ein Attribut oder Element zu, bei dem für TypedValueinvalid angegeben ist, wird eine XPathNavigator ausgelöst .

Um beim Zugriff auf Attribute oder Elemente mit dem Validity zu bestimmen, ob das jeweilige Attribut oder Element gültig ist, kann die XPathNavigator-Eigenschaft verwendet werden.

Hinweis

Wenn ein XML-Dokument in ein XmlDocument-Objekt mit einem zugeordneten Schema geladen wird, das Standardwerte definiert, behandelt das XmlDocument-Objekt diese Standardwerte, als wären diese im XML-Dokument enthalten. Das bedeutet, dass die IsEmptyElement-Eigenschaft immer false für ein Element zurückgibt, das vom Schema als Standard verwendet wird, auch wenn es im XML-Dokument als leeres Element geschrieben wurde.

Validieren eines Dokuments mithilfe der Validate-Methode

Die Validate-Methode der XmlDocument-Klasse validiert das in einem XmlDocument-Objekt enthaltene XML-Dokument anhand des in der XmlDocument-Eigenschaft des Schemas-Objekts angegebenen Schemas und führt den Zuwachs des Infosets durch. Dadurch wird ein zuvor nicht typisiertes XML-Dokument im XmlDocument-Objekt durch ein typisiertes Dokument ersetzt.

Das XmlDocument-Objekt meldet Schemavalidierungsfehler und -warnungen mithilfe des ValidationEventHandler-Delegaten, der als Parameter an die Validate-Methode übergeben wird.

Im folgenden Beispiel wird die im contosoBooks.xml-Objekt enthaltene XmlDocument-Datei anhand des contosoBooks.xsd-Schemas validiert, das in der XmlDocument-Eigenschaft des Schemas-Objekts enthalten ist.

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("http://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("http://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;  
        }  
    }  
}  

In diesem Beispiel wird die Datei contosoBooks.xml als Eingabe verwendet.

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

In diesem Beispiel wird auch contosoBooks.xsd als Eingabe verwendet.

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

Validierungsänderungen

Nachdem an einem XML-Dokument Änderungen vorgenommen wurden, können Sie die Änderungen anhand des Schemas des XML-Dokuments mithilfe der Validate-Methode der XmlDocument-Klasse validieren.

Im folgenden Beispiel wird die contosoBooks.xml-Datei beim Laden in das XmlDocument-Objekt validiert, indem das XmlDocument-Objekt mithilfe eines validierenden XmlReader-Objekts erstellt wird. Das XML-Dokument ist erfolgreich validiert, wenn es ohne Eintreten von Schemavalidierungsfehlern oder -warnungen geladen werden kann. Im Beispiel werden dann zwei Änderungen am XML-Dokument vorgenommen, die gemäß des contosoBooks.xsd-Schemas ungültig sind. Bei der ersten Änderung wird ein ungültiges untergeordnetes Element eingefügt, wodurch ein Schemavalidierungsfehler eintritt. Bei der zweiten Änderung wird der Wert einer typisierten Knotens auf einen Wert festgelegt, der gemäß des Typs des Knotens ungültig ist, wodurch eine Ausnahme ausgelöst wird.

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("http://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", "http://www.contoso.com/books")  
            navigator.MoveToChild("book", "http://www.contoso.com/books")  
            navigator.MoveToChild("author", "http://www.contoso.com/books")  
  
            navigator.AppendChild("<title>Book Title</title>")  
  
            document.Validate(validation)  
  
            navigator.MoveToParent()  
            navigator.MoveToChild("price", "http://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("http://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", "http://www.contoso.com/books");  
            navigator.MoveToChild("book", "http://www.contoso.com/books");  
            navigator.MoveToChild("author", "http://www.contoso.com/books");  
  
            navigator.AppendChild("<title>Book Title</title>");  
  
            document.Validate(validation);  
  
            navigator.MoveToParent();  
            navigator.MoveToChild("price", "http://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;  
        }  
    }  
}  

In diesem Beispiel wird die Datei contosoBooks.xml als Eingabe verwendet.

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

In diesem Beispiel wird auch contosoBooks.xsd als Eingabe verwendet.

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

In dem Beispiel oben werden zwei Änderungen an dem XML-Dokument vorgenommen, das im XmlDocument-Objekt enthalten ist. Beim Laden des XML-Dokuments wären alle festgestellten Schemavalidierungsfehler von der Methode des Ereignishandlers für die Validierung behandelt und auf der Konsole ausgegeben worden.

In diesem Beispiel sind die Validierungsfehler nach dem Laden des XML-Dokuments eingetreten und wurden mithilfe der Validate-Methode der XmlDocument-Klasse gefunden.

Änderungen, die mithilfe der SetTypedValue-Methode der XPathNavigator-Klasse vorgenommen wurden, hatten eine InvalidCastException zur Folge, da der neue Wert gemäß des Schematyps des Knotens ungültig war.

Weitere Informationen zum Ändern von Werten mithilfe der SetTypedValue-Methode finden Sie unter dem Thema Ändern von XML-Daten mit XPathNavigator.

Schreibgeschützte Validierung

Die XPathDocument-Klasse ist eine schreibgeschützte Darstellung eines XML-Dokuments im Speicher. Sowohl die XPathDocument-Klasse als auch die XmlDocument-Klasse erstellen XPathNavigator-Objekte zum Navigieren und zum Bearbeiten von XML-Dokumenten. Da die XPathDocument-Klasse schreibgeschützt ist, können von XPathNavigator-Objekten zurückgegebene XPathDocument-Objekte das im XPathDocument-Objekt enthaltene XML-Dokument nicht bearbeiten.

Bei der Validierung können Sie ein XPathDocument-Objekt auf die gleiche Weise erstellen, wie ein XmlDocument-Objekt mithilfe eines validierenden XmlReader-Objekts erstellt wird, wie bereits in diesem Thema erläutert. Das XPathDocument-Objekt validiert das XML-Dokument beim Ladevorgang. Da die XML-Daten jedoch im XPathDocument-Objekt nicht bearbeitet werden können, können Sie das XML-Dokument nicht erneut validieren.

Weitere Informationen zu schreibgeschützten und bearbeitbaren XPathNavigator-Objekten finden Sie in dem Thema Lesen von XML-Daten mithilfe von XPathDocument und XmlDocument.

Siehe auch