Attraversamento di schemi XML

L'attraversamento di uno schema XML mediante l'API del modello SOM (Schema Object Model) consente di accedere a elementi, attributi e tipi archiviati nel modello SOM. Tale attraversamento rappresenta inoltre il primo passaggio per la modifica di uno schema XML tramite l'API del modello SOM.

Attraversamento di uno schema XML

Le seguenti proprietà della classe XmlSchema forniscono l'accesso alla raccolta degli elementi globali aggiunti a XML Schema.

Proprietà Tipo di oggetto archiviato nella raccolta o nella matrice
Elements XmlSchemaElement
Attributes XmlSchemaAttribute
AttributeGroups XmlSchemaAttributeGroup
Groups XmlSchemaGroup
Includes XmlSchemaExternal, XmlSchemaInclude, XmlSchemaImport o XmlSchemaRedefine
Items XmlSchemaObject (fornisce l'accesso a elementi, attributi e tipi a livello globale).
Notations XmlSchemaNotation
SchemaTypes XmlSchemaType, XmlSchemaSimpleType, XmlSchemaComplexType
UnhandledAttributes XmlAttribute (fornisce l'accesso agli attributi che non appartengono allo spazio dei nomi dello schema).

Nota

Tutte le proprietà elencate nella precedente tabella, a eccezione della proprietà Items, sono proprietà PSCI (Post-Schema-Compilation-Infoset) che non sono disponibili fino a quando lo schema non è stato compilato. La proprietà Items è una proprietà precedente alla compilazione dello schema che può essere usata prima che lo schema venga compilato per accedere e apportare modifiche a elementi, attributi e tipi a livello globale.

La proprietà UnhandledAttributes fornisce l'accesso agli attributi che non appartengono allo spazio dei nomi dello schema. Tali attributi non vengono elaborati dal processore dello schema.

Nel seguente esempio di codice viene illustrato l'attraversamento dello schema del cliente creato nell'argomento Compilazione di XML Schema. Nell'esempio di codice viene eseguito l'attraversamento dello schema usando le raccolte descritte in precedenza e tutti gli elementi e attributi dello schema vengono scritti nella console.

L'esempio consente di attraversare lo schema del cliente eseguendo i passaggi seguenti.

  1. Aggiunge lo schema del cliente a un nuovo oggetto XmlSchemaSet, quindi lo compila. Eventuali avvisi ed errori di convalida dello schema rilevati durante la lettura e la compilazione dello schema vengono gestiti dal delegato ValidationEventHandler.

  2. Recupera l'oggetto XmlSchema compilato dal tipo XmlSchemaSet scorrendo la proprietà Schemas. Dal momento che lo schema è stato compilato, è possibile accedere alle proprietà di PSCI (Post-Schema-Compilation-Infoset).

  3. Scorre ciascun tipo XmlSchemaElement nella raccolta Values della raccolta XmlSchema.Elements successiva alla compilazione dello schema e scrive il nome di ciascun elemento nella console.

  4. Ottiene il tipo complesso dell'elemento Customer usando la classe XmlSchemaComplexType.

  5. Se il tipo complesso dispone di attributi, ottiene un tipo IDictionaryEnumerator per enumerare ciascun tipo XmlSchemaAttribute e scrive il relativo nome nella console.

  6. Ottiene la particella di sequenza del tipo complesso usando la classe XmlSchemaSequence.

  7. Scorre ciascun tipo XmlSchemaElement nella raccolta XmlSchemaSequence.Items e scrive il nome di ciascun elemento figlio nella console.

Di seguito è riportato l'esempio di codice completo.

#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

Se è un tipo semplice o un tipo complesso definito dall'utente, il tipo della proprietà XmlSchemaElement.ElementSchemaType può essere XmlSchemaSimpleType o XmlSchemaComplexType. Se è uno dei tipi di dati incorporati definiti nella raccomandazione W3C relativa agli schemi XML, il tipo della proprietà può essere anche XmlSchemaDatatype. Nello schema del cliente, il tipo della proprietà ElementSchemaType dell'elemento Customer è XmlSchemaComplexType e il tipo degli elementi FirstName e LastName è XmlSchemaSimpleType.

Nell'esempio di codice dell'argomento Compilazione di XML Schema è stata usata la raccolta XmlSchemaComplexType.Attributes per aggiungere l'attributo CustomerId all'elemento Customer. Questa è una proprietà precedente alla compilazione dello schema. La proprietà PSCI corrispondente è la raccolta XmlSchemaComplexType.AttributeUses, che contiene tutti gli attributi del tipo complesso, inclusi quelli ereditati tramite una derivazione del tipo.

Vedi anche