Durchlaufen von XML-Schemata

Das Durchlaufen eines XML-Schemas mithilfe einer SOM-API (Schema Object Model) ermöglicht den Zugriff auf die im SOM gespeicherten Elemente, Attribute und Typen. Der erste Schritt beim Bearbeiten eines XML-Schemas mithilfe der SOM-API ist das Durchlaufen des im SOM geladenen XML-Schemas.

Durchlaufen eines XML-Schemas

Die folgenden Eigenschaften der XmlSchema-Klasse ermöglichen einen Zugriff auf die Auflistung aller globalen Elemente, die dem XML-Schema hinzugefügt wurden.

Eigenschaft Objekttyp, der in der Auflistung oder im Array gespeichert ist
Elements XmlSchemaElement
Attributes XmlSchemaAttribute
AttributeGroups XmlSchemaAttributeGroup
Groups XmlSchemaGroup
Includes XmlSchemaExternal, XmlSchemaInclude, XmlSchemaImport oder XmlSchemaRedefine
Items XmlSchemaObject (ermöglicht den Zugriff auf alle Elemente, Attribute und Typen auf globaler Ebene).
Notations XmlSchemaNotation
SchemaTypes XmlSchemaType, XmlSchemaSimpleType, XmlSchemaComplexType
UnhandledAttributes XmlAttribute (ermöglicht den Zugriff auf Attribute, die nicht zum Schemanamespace gehören)

Hinweis

Alle in der obigen Tabelle aufgelisteten Eigenschaften (mit Ausnahme der Items-Eigenschaft) sind PSCI-Eigenschaften (Post-Schema-Compilation-Infoset), die erst nach dem Kompilieren des Schemas zur Verfügung stehen. Die Items-Eigenschaft ist eine Eigenschaft vor der Kompilierung des Schemas, mit der vor der Kompilierung des Schemas auf Elemente, Attribute und Typen auf globaler Ebene zugegriffen bzw. diese bearbeitet werden können.

Die UnhandledAttributes-Eigenschaft ermöglicht den Zugriff auf alle Attribute, die nicht zum Schemanamespace gehören. Diese Attribute werden bei der Schemaverarbeitung nicht verarbeitet.

Im folgenden Codebeispiel wird das Durchlaufen des Kundenschemas veranschaulicht, das im Thema Erstellen von XML-Schemata erstellt wurde. Im Codebeispiel werden das Durchlaufen des Schemas mithilfe der oben beschriebenen Auflistungen und das Schreiben aller Elemente und Attribute im Schema in die Konsole veranschaulicht.

Im Codebeispiel wird das Kundenschema in den folgenden Schritten durchlaufen.

  1. Fügt das Kundenschema einem neuen XmlSchemaSet-Objekt hinzu und kompiliert es anschließend. Alle beim Lesen oder Kompilieren des Schemas aufgetretenen Schemavalidierungswarnungen und -fehler werden vom ValidationEventHandler-Delegaten behandelt.

  2. Ruft das kompilierte XmlSchema-Objekt aus XmlSchemaSet ab, indem die Schemas-Eigenschaft durchlaufen wird. Da das Schema kompiliert ist, kann auf die Eigenschaften im PSCI zugegriffen werden.

  3. Durchläuft jedes XmlSchemaElement in der Values-Auflistung der Post-Schema-Compilation-XmlSchema.Elements-Auflistung. Dabei werden die Namen der einzelnen Elemente in die Konsole geschrieben.

  4. Ruft den komplexen Typ des Customer-Elements mithilfe der XmlSchemaComplexType-Klasse ab.

  5. Wenn der komplexe Typ über Attribute verfügt, wird ein IDictionaryEnumerator abgerufen, um jedes XmlSchemaAttribute aufzuzählen und den Namen in die Konsole zu schreiben.

  6. Ruft den sequenceXmlSchemaSequence-Partikel des komplexen Typs mithilfe der -Klasse ab.

  7. Durchläuft jedes XmlSchemaElement in der XmlSchemaSequence.Items-Auflistung und schreibt die Namen der einzelnen untergeordneten Elemente in die Konsole.

Nachfolgend ist das vollständige Codebeispiel angegeben.

#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

Die XmlSchemaElement.ElementSchemaType-Eigenschaft kann XmlSchemaSimpleType oder XmlSchemaComplexType sein, wenn es sich um einen benutzerdefinierten einfachen oder komplexen Typ handelt. Sie kann auch XmlSchemaDatatype sein, wenn es sich um einen der integrierten Datentypen handelt, die in der XML-Schemaempfehlung des W3C definiert sind. Im Kundenschema ist der ElementSchemaType des Customer-Elements XmlSchemaComplexType, und das FirstName-Element und das LastName-Element sind XmlSchemaSimpleType.

Im Codebeispiel im Thema Erstellen von XML-Schemata wurde mithilfe der XmlSchemaComplexType.Attributes-Auflistung dem Customer-Element das CustomerId-Attribut hinzugefügt. Es handelt sich dabei um eine Eigenschaft vor der Kompilierung des Schemas. Die zugehörige PSCI-Eigenschaft (Post-Schema-Validation Infoset) ist die XmlSchemaComplexType.AttributeUses-Auflistung, in der alle Attribute der komplexen Typen enthalten sind, einschließlich der durch Ableitung geerbten Attribute.

Siehe auch