Partager via


Validation de schéma à l'aide de XPathNavigator

La classe XmlDocument permet de valider le contenu XML d'un objet XmlDocument de deux manières. La première consiste à valider le contenu XML à l'aide d'un objet XmlReader de validation et la seconde, à utiliser la méthode Validate de la classe XmlDocument. Vous pouvez également effectuer une validation en lecture seule du contenu XML à l'aide de la classe XPathDocument.

Validation de données XML

La classe XmlDocument ne valide pas de document XML à l'aide d'une DTD ou d'une validation de schéma de langage XSD (XML schema definition) par défaut. Elle vérifie uniquement que le document XML est correctement construit.

La première manière de valider un document XML consiste à valider le document lors de son chargement dans un objet XmlDocument à l'aide d'un objet XmlReader de validation. La seconde consiste à valider un document XML précédemment non typé à l'aide de la méthode Validate de la classe XmlDocument. Dans les deux cas, toute modification apportée au document XML validé peut être revalidée à l'aide de la méthode Validate de la classe XmlDocument.

Validation d'un document lors de son chargement

Un objet XmlReader de validation est créé par la transmission d'un objet XmlReaderSettings à la méthode Create de la classe XmlReader qui prend un objet XmlReaderSettings comme paramètre. L'objet XmlReaderSettings transmis sous la forme d'un paramètre possède une propriété ValidationType définie sur Schema et un schéma XML pour le document XML contenu dans l'objet XmlDocument ajouté à sa propriété Schemas. L'objet XmlReader de validation permet ensuite de créer l'objet XmlDocument.

L'exemple suivant valide le fichier contosoBooks.xml lors de son chargement dans l'objet XmlDocument en créant l'objet XmlDocument à l'aide d'un objet XmlReader de validation. Comme le document XML est valide par rapport à son schéma, aucun avertissement ou aucune erreur de validation de schéma n'est générée.

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

L'exemple prend le fichier contosoBooks.xml comme entrée.

<?xml version="1.0" encoding="utf-8" ?>
<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>

L'exemple prend également le fichier contosoBooks.xsd comme entrée.

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

Dans l'exemple ci-dessus, une XmlSchemaValidationException est levée quand Load est appelé si un type d'attribut ou d'élément ne correspond pas au type spécifié dans le schéma de validation. Si un ValidationEventHandler est défini sur la XmlReader de validation, le ValidationEventHandler est appelé chaque fois qu'un type non valide est rencontré.

Une XmlSchemaException est levée si le XPathNavigator accède à un attribut ou à un élément dont le TypedValue est défini sur invalid.

La propriété Validity peut être utilisée pour déterminer si un attribut ou un élément est valide ou non lors de l'accès aux attributs ou éléments avec le XPathNavigator.

RemarqueRemarque

Lorsqu'un document XML est chargé dans un objet XmlDocument avec un schéma associé qui définit les valeurs par défaut, l'objet XmlDocument traite ces valeurs par défaut comme si elles apparaissaient dans le document XML.Ceci signifie que la propriété IsEmptyElement retourne toujours false pour un élément dont la valeur par défaut provenait du schéma, même s'il était écrit comme élément vide dans le document XML.

Validation d'un document à l'aide de la méthode Validate

La méthode Validate de la classe XmlDocument valide le document XML contenu dans un objet XmlDocument par rapport aux schémas spécifiés dans la propriété Schemas de l'objet XmlDocument et effectue une augmentation infoset. En guise de résultat, un document XML précédemment non typé dans l'objet XmlDocument est remplacé par un document typé.

L'objet XmlDocument signale des avertissements et des erreurs de validation de schéma à l'aide du délégué ValidationEventHandler transmis sous la forme d'un paramètre à la méthode Validate.

L'exemple suivant valide le fichier contosoBooks.xml contenu dans l'objet XmlDocument par rapport au schéma contosoBooks.xsd contenu dans la propriété Schemas de l'objet XmlDocument.

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

L'exemple prend le fichier contosoBooks.xml comme entrée.

<?xml version="1.0" encoding="utf-8" ?>
<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>

L'exemple prend également le fichier contosoBooks.xsd comme entrée.

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

Validation de modifications

Une fois que vous avez modifié un document XML, vous pouvez valider les modifications par rapport au schéma pour le document XML à l'aide de la méthode Validate de la classe XmlDocument.

L'exemple suivant valide le fichier contosoBooks.xml lors de son chargement dans l'objet XmlDocument en créant l'objet XmlDocument à l'aide d'un objet XmlReader de validation. Le document XML est correctement validé lors de son chargement et aucun avertissement ou aucune erreur de validation de schéma n'est générée. L'exemple apporte ensuite deux modifications au document XML non valides par rapport au schéma contosoBooks.xsd. La première modification insère un élément enfant non valide, provoquant une erreur de validation de schéma et la deuxième modification définit la valeur d'un nœud typé sur une valeur non valide par rapport au type de nœud, provoquant une erreur.

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

L'exemple prend le fichier contosoBooks.xml comme entrée.

<?xml version="1.0" encoding="utf-8" ?>
<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>

L'exemple prend également le fichier contosoBooks.xsd comme entrée.

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

Dans l'exemple ci-dessus, deux modifications sont apportées au document XML contenu dans l'objet XmlDocument. Lors du chargement du document XML, toute erreur de validation de schéma rencontrée doit avoir été traitée par la méthode du gestionnaire d'événements de validation et écrite dans la console.

Dans cet exemple, les erreurs de validation ont été introduites après le chargement du document XML et trouvées à l'aide de la méthode Validate de la classe XmlDocument.

Les modifications apportées à l'aide de la méthode SetTypedValue de la classe XPathNavigator ont généré une InvalidCastException car la nouvelle valeur était non valide par rapport au type de schéma du nœud.

Pour plus d'informations sur la modification de valeurs à l'aide de la méthode SetTypedValue, voir la rubrique Modification de données XML à l'aide de XPathNavigator.

Validation en lecture seule

La classe XPathDocument est une représentation en lecture seule et en mémoire d'un document XML. Les classes XPathDocument et XmlDocument créent des objets XPathNavigator permettant de parcourir et de modifier des documents XML. Étant donné que la classe XPathDocument est une classe en lecture seule, l'objet XPathNavigator retourné par les objets XPathDocument ne peut pas modifier le document XML contenu dans l'objet XPathDocument.

En cas de validation, vous pouvez créer un objet XPathDocument de la même manière qu'un objet XmlDocument à l'aide d'un objet XmlReader de validation comme décrit précédemment dans cette rubrique. L'objet XPathDocument valide le document XML lors de son chargement, mais comme vous ne pouvez pas modifier les données XML dans l'objet XPathDocument, vous ne pouvez pas revalider le document XML.

Pour plus d'informations sur les objets XPathNavigator modifiables et en lecture seule, voir la rubrique Lecture de données XML à l'aide de XPathDocument et XmlDocument.

Voir aussi

Référence

XmlDocument

XPathDocument

XPathNavigator

Concepts

Traitement des données XML à l'aide du modèle de données XPath

Lecture de données XML à l'aide de XPathDocument et XmlDocument

Sélection, évaluation et mise en correspondance de données XML à l'aide de XPathNavigator

Accès à des données XML à l'aide de XPathNavigator

Modification de données XML à l'aide de XPathNavigator