Cómo atravesar esquemas XML
Al atravesar un esquema XML con la API del Modelo de objetos de esquema (SOM), se obtiene acceso a los elementos, atributos y tipos almacenados en el SOM. Atravesar un esquema XML cargado en el SOM es también el primer paso para editar un esquema XML utilizando la API del SOM.
Cómo atravesar un esquema XML
Las siguientes propiedades de la clase XmlSchema proporcionan acceso a la colección de todos los elementos globales que se agregan al esquema XML.
Propiedad. | Tipo de objeto almacenado en la colección o matriz |
---|---|
Elements | XmlSchemaElement |
Attributes | XmlSchemaAttribute |
AttributeGroups | XmlSchemaAttributeGroup |
Groups | XmlSchemaGroup |
Includes | XmlSchemaExternal, XmlSchemaInclude, XmlSchemaImport o XmlSchemaRedefine |
Items | XmlSchemaObject (proporciona acceso a todos los tipos, atributos y elementos de nivel globales). |
Notations | XmlSchemaNotation |
SchemaTypes | XmlSchemaType, XmlSchemaSimpleType, XmlSchemaComplexType |
UnhandledAttributes | XmlAttribute (proporciona acceso a atributos que no pertenecen al espacio de nombres del esquema) |
Nota
Todas las propiedades que se enumeran en la tabla anterior, excepto la propiedad Items, son propiedades del conjunto de información posterior a la compilación de esquemas que no están disponibles hasta que se ha compilado el esquema. La propiedad Items es una propiedad anterior a la compilación del esquema que se puede utilizar antes de que se haya compilado el esquema para tener acceso y editar todos los tipos, atributos y elementos de nivel globales.
La propiedad UnhandledAttributes proporciona acceso a todos atributos que no pertenecen al espacio de nombres del esquema. El procesador de esquemas no procesa estos atributos.
En el código de ejemplo que se incluye a continuación se muestra cómo se atraviesa el esquema del cliente que se creó en el tema Compilar esquemas XML. El código de ejemplo muestra cómo se atraviesa el esquema utilizando las colecciones que se han descrito anteriormente y escribe todos los elementos y atributos del esquema en la consola.
El ejemplo atraviesa el esquema del cliente en los siguientes pasos.
Agrega el esquema del cliente a un objeto XmlSchemaSet nuevo y luego lo compila. Cualquier error o advertencia de validación de esquemas que se encuentre durante la lectura o compilación del esquema se controla por medio del delegado ValidationEventHandler.
Recupera el objeto XmlSchema compilado desde XmlSchemaSet iterando por la propiedad Schemas. Puesto que el esquema se compila, las propiedades del conjunto de información posterior a la compilación del esquema son accesibles.
Itera por cada XmlSchemaElement en la colección Values de la colección XmlSchema.Elements posterior a la compilación del esquema escribiendo el nombre de cada elemento en la consola.
Obtiene el tipo complejo del elemento
Customer
utilizando la clase XmlSchemaComplexType.Si el tipo complejo tiene algún atributo, obtiene un IDictionaryEnumerator para realizar la enumeración por cada XmlSchemaAttribute y escribe su nombre en la consola.
Obtiene la partícula de secuencia del tipo complejo utilizando la clase XmlSchemaSequence.
Itera por cada XmlSchemaElement de la colección XmlSchemaSequence.Items escribiendo el nombre de cada elemento secundario en la consola.
Éste es el ejemplo de código 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
La propiedad XmlSchemaElement.ElementSchemaType puede ser XmlSchemaSimpleType o XmlSchemaComplexType si se trata de un tipo complejo o un tipo simple definido por el usuario. También puede ser XmlSchemaDatatype si es uno de los tipos de datos integrados que se definen en la recomendación de esquemas XML del W3C. En el esquema del cliente, el ElementSchemaType del elemento Customer
es XmlSchemaComplexType, y los elementos FirstName
y LastName
son XmlSchemaSimpleType.
El código de ejemplo del tema Compilar esquemas XML utilizaba la colección XmlSchemaComplexType.Attributes para agregar el atributo CustomerId
al elemento Customer
. Se trata de una propiedad anterior a la compilación del esquema. La propiedad del conjunto de información posterior a la compilación del esquema correspondiente es la colección XmlSchemaComplexType.AttributeUses, que contiene todos los atributos del tipo complejo, incluyendo los que se heredan a través de la derivación de tipos.