Partager via


Traversée de schémas XML

Traverser un schéma XML à l'aide de l'API SOM (Schema Object Model) permet d'accéder aux éléments, attributs et types stockés dans le SOM. Traverser un schéma XML chargé dans le SOM est également la première étape de l'édition d'un schéma XML avec l'API SOM.

Traversée d'un schéma XML

Les propriétés suivantes de la classe XmlSchema fournissent un accès à la collection de tous les éléments globaux ajoutés au schéma XML.

Propriété Type d’objet stocké dans la collection ou le tableau
Elements XmlSchemaElement
Attributes XmlSchemaAttribute
AttributeGroups XmlSchemaAttributeGroup
Groups XmlSchemaGroup
Includes XmlSchemaExternal, XmlSchemaInclude, XmlSchemaImport ou XmlSchemaRedefine
Items Objet XmlSchemaObject (fournit un accès à tous les éléments, attributs et types de niveau global).
Notations XmlSchemaNotation
SchemaTypes XmlSchemaType, XmlSchemaSimpleType, XmlSchemaComplexType
UnhandledAttributes Objet XmlAttribute (fournit un accès aux attributs qui n'appartiennent pas à l'espace de noms du schéma)

Notes

Toutes les propriétés répertoriées dans le tableau ci-dessus, à l'exception de la propriété Items, sont des propriétés PSCI (Post-Schema-Compilation-Infoset) qui ne sont pas disponibles tant que le schéma n'a pas été compilé. La propriété Items est une propriété de pré-compilation de schéma qui peut être utilisée avant que le schéma ait été compilé afin d'accéder à et d'éditer tous les éléments, attributs et types de niveau global.

La propriété UnhandledAttributes permet d'accéder à tous les attributs qui n'appartiennent pas à l'espace de noms du schéma. Ces attributs ne sont pas traités par le processeur de schéma.

L'exemple de code suivant illustre la traversée du schéma utilisateur créé dans la rubrique Création de schémas XML. Il illustre la traversée du schéma à l'aide des collections décrites ci-dessus et l'envoi à la console de tous les éléments et attributs contenus dans le schéma.

Cet exemple de code traverse le schéma utilisateur en plusieurs étapes comme suit.

  1. Il ajoute le schéma utilisateur à un nouvel objet XmlSchemaSet puis le compile. Les avertissements et erreurs de validation de schéma éventuellement rencontrés pendant la lecture ou la compilation du schéma sont traités par le délégué ValidationEventHandler.

  2. Il extrait l'objet XmlSchema compilé de l'objet XmlSchemaSet en effectuant une itération sur la propriété Schemas. Le schéma étant compilé, les propriétés PSCI (Post-Schema-Compilation-Infoset) sont accessibles.

  3. Il effectue une itération sur chaque objet XmlSchemaElement figurant dans la collection Values de la collection de post-compilation de schéma XmlSchema.Elements et écrit le nom de chaque élément à la console.

  4. Il obtient le type complexe de l'élément Customer en utilisant la classe XmlSchemaComplexType.

  5. Si le type complexe possède des attributs, il obtient un objet IDictionaryEnumerator à énumérer sur chaque objet XmlSchemaAttribute et en écrit le nom à la console.

  6. Il obtient la particule de séquence du type complexe en utilisant la classe XmlSchemaSequence.

  7. Il effectue une itération sur chaque objet XmlSchemaElement figurant dans la collection XmlSchemaSequence.Items et écrit le nom de chaque élément enfant à la console.

Voici l'exemple de code complet.

#using <System.Xml.dll>

using namespace System;
using namespace System::Collections;
using namespace System::Xml;
using namespace System::Xml::Schema;

ref class XmlSchemaTraverseExample
{
public:

    static void Main()
    {
        // Add the customer schema to a new XmlSchemaSet and compile it.
        // Any schema validation warnings and errors encountered reading or 
        // compiling the schema are handled by the ValidationEventHandler delegate.
        XmlSchemaSet^ schemaSet = gcnew XmlSchemaSet();
        schemaSet->ValidationEventHandler += gcnew ValidationEventHandler(ValidationCallback);
        schemaSet->Add("http://www.tempuri.org", "customer.xsd");
        schemaSet->Compile();

        // Retrieve the compiled XmlSchema object from the XmlSchemaSet
        // by iterating over the Schemas property.
        XmlSchema^ customerSchema = nullptr;
        for each (XmlSchema^ schema in schemaSet->Schemas())
        {
            customerSchema = schema;
        }

        // Iterate over each XmlSchemaElement in the Values collection
        // of the Elements property.
        for each (XmlSchemaElement^ element in customerSchema->Elements->Values)
        {

            Console::WriteLine("Element: {0}", element->Name);

            // Get the complex type of the Customer element.
            XmlSchemaComplexType^ complexType = dynamic_cast<XmlSchemaComplexType^>(element->ElementSchemaType);

            // If the complex type has any attributes, get an enumerator 
            // and write each attribute name to the console.
            if (complexType->AttributeUses->Count > 0)
            {
                IDictionaryEnumerator^ enumerator =
                    complexType->AttributeUses->GetEnumerator();

                while (enumerator->MoveNext())
                {
                    XmlSchemaAttribute^ attribute =
                        dynamic_cast<XmlSchemaAttribute^>(enumerator->Value);

                    Console::WriteLine("Attribute: {0}", attribute->Name);
                }
            }

            // Get the sequence particle of the complex type.
            XmlSchemaSequence^ sequence = dynamic_cast<XmlSchemaSequence^>(complexType->ContentTypeParticle);

            // Iterate over each XmlSchemaElement in the Items collection.
            for each (XmlSchemaElement^ childElement in sequence->Items)
            {
                Console::WriteLine("Element: {0}", childElement->Name);
            }
        }
    }

    static void ValidationCallback(Object^ sender, ValidationEventArgs^ args)
    {
        if (args->Severity == XmlSeverityType::Warning)
            Console::Write("WARNING: ");
        else if (args->Severity == XmlSeverityType::Error)
            Console::Write("ERROR: ");

        Console::WriteLine(args->Message);
    }
};

int main()
{
    XmlSchemaTraverseExample::Main();
    return 0;
};
using System;
using System.Collections;
using System.Xml;
using System.Xml.Schema;

class XmlSchemaTraverseExample
{
    static void Main()
    {
        // Add the customer schema to a new XmlSchemaSet and compile it.
        // Any schema validation warnings and errors encountered reading or
        // compiling the schema are handled by the ValidationEventHandler delegate.
        XmlSchemaSet schemaSet = new XmlSchemaSet();
        schemaSet.ValidationEventHandler += new ValidationEventHandler(ValidationCallback);
        schemaSet.Add("http://www.tempuri.org", "customer.xsd");
        schemaSet.Compile();

        // Retrieve the compiled XmlSchema object from the XmlSchemaSet
        // by iterating over the Schemas property.
        XmlSchema customerSchema = null;
        foreach (XmlSchema schema in schemaSet.Schemas())
        {
            customerSchema = schema;
        }

        // Iterate over each XmlSchemaElement in the Values collection
        // of the Elements property.
        foreach (XmlSchemaElement element in customerSchema.Elements.Values)
        {

            Console.WriteLine("Element: {0}", element.Name);

            // Get the complex type of the Customer element.
            XmlSchemaComplexType complexType = element.ElementSchemaType as XmlSchemaComplexType;

            // If the complex type has any attributes, get an enumerator
            // and write each attribute name to the console.
            if (complexType.AttributeUses.Count > 0)
            {
                IDictionaryEnumerator enumerator =
                    complexType.AttributeUses.GetEnumerator();

                while (enumerator.MoveNext())
                {
                    XmlSchemaAttribute attribute =
                        (XmlSchemaAttribute)enumerator.Value;

                    Console.WriteLine("Attribute: {0}", attribute.Name);
                }
            }

            // Get the sequence particle of the complex type.
            XmlSchemaSequence sequence = complexType.ContentTypeParticle as XmlSchemaSequence;

            // Iterate over each XmlSchemaElement in the Items collection.
            foreach (XmlSchemaElement childElement in sequence.Items)
            {
                Console.WriteLine("Element: {0}", childElement.Name);
            }
        }
    }

    static void ValidationCallback(object sender, ValidationEventArgs args)
    {
        if (args.Severity == XmlSeverityType.Warning)
            Console.Write("WARNING: ");
        else if (args.Severity == XmlSeverityType.Error)
            Console.Write("ERROR: ");

        Console.WriteLine(args.Message);
    }
}
Imports System.Collections
Imports System.Xml
Imports System.Xml.Schema

Class XmlSchemaTraverseExample

    Shared Sub Main()

        ' Add the customer schema to a new XmlSchemaSet and compile it.
        ' Any schema validation warnings and errors encountered reading or 
        ' compiling the schema are handled by the ValidationEventHandler delegate.
        Dim schemaSet As XmlSchemaSet = New XmlSchemaSet()
        AddHandler schemaSet.ValidationEventHandler, AddressOf ValidationCallback
        schemaSet.Add("http://www.tempuri.org", "customer.xsd")
        schemaSet.Compile()

        ' Retrieve the compiled XmlSchema object from the XmlSchemaSet
        ' by iterating over the Schemas property.
        Dim customerSchema As XmlSchema = Nothing
        For Each schema As XmlSchema In schemaSet.Schemas()
            customerSchema = schema
        Next

        ' Iterate over each XmlSchemaElement in the Values collection
        ' of the Elements property.
        For Each element As XmlSchemaElement In customerSchema.Elements.Values

            Console.WriteLine("Element: {0}", element.Name)

            ' Get the complex type of the Customer element.
            Dim complexType As XmlSchemaComplexType = CType(element.ElementSchemaType, XmlSchemaComplexType)

            ' If the complex type has any attributes, get an enumerator 
            ' and write each attribute name to the console.
            If complexType.AttributeUses.Count > 0 Then

                Dim enumerator As IDictionaryEnumerator = _
                    complexType.AttributeUses.GetEnumerator()

                While enumerator.MoveNext()

                    Dim attribute As XmlSchemaAttribute = _
                        CType(enumerator.Value, XmlSchemaAttribute)

                    Console.WriteLine("Attribute: {0}", Attribute.Name)
                End While
            End If

            ' Get the sequence particle of the complex type.
            Dim sequence As XmlSchemaSequence = CType(complexType.ContentTypeParticle, XmlSchemaSequence)

            For Each childElement As XmlSchemaElement In sequence.Items
                Console.WriteLine("Element: {0}", childElement.Name)
            Next
        Next

    End Sub

    Shared Sub ValidationCallback(ByVal sender As Object, ByVal args As ValidationEventArgs)
        If args.Severity = XmlSeverityType.Warning Then
            Console.Write("WARNING: ")
        Else
            If args.Severity = XmlSeverityType.Error Then
                Console.Write("ERROR: ")
            End If
        End If
        Console.WriteLine(args.Message)
    End Sub

End Class

La propriété XmlSchemaElement.ElementSchemaType peut être l'objet XmlSchemaSimpleType ou XmlSchemaComplexType si c'est un type complexe ou un type simple défini par l'utilisateur. Elle peut aussi être l'objet XmlSchemaDatatype si c'est un des types de données intégrés définis dans la recommandation du W3C sur le schéma XML. Dans le schéma utilisateur, la propriété ElementSchemaType de l'élément Customer est l'objet XmlSchemaComplexType et les éléments FirstName et LastName sont des objets XmlSchemaSimpleType.

L'exemple de code de la rubrique Création de schémas XML utilisait la collection XmlSchemaComplexType.Attributes pour ajouter l'attribut CustomerId à l'élément Customer. C'est une propriété de pré-compilation de schéma. La propriété PSCI correspondante est la collection XmlSchemaComplexType.AttributeUses, qui contient tous les attributs du type complexe, y compris ceux qui sont hérités par dérivation de type.

Voir aussi