Inclusión o importación de esquemas XML
Un esquema XML puede contener elementos <xs:import />
, <xs:include />
y <xs:redefine />
. Estos elementos de esquema hacen referencia a otros esquemas XML que se pueden utilizar para complementar la estructura del esquema que los incluye o importa. Las clases XmlSchemaImport, XmlSchemaInclude y XmlSchemaRedefine se asignan estos elementos en la API del modelo de objetos de esquema (SOM).
Inclusión o importación de un esquema XML
En el siguiente ejemplo de código se complementa el esquema del cliente que se creó en el tema Compilar esquemas XML con el esquema de direcciones. Al complementar el esquema del cliente con el esquema de direcciones, los tipos de direcciones están disponibles en el esquema del cliente.
El esquema de direcciones se puede incorporar utilizando los elementos <xs:include />
o <xs:import />
para utilizar los componentes del esquema de direcciones tal y como están, o utilizando un elemento <xs:redefine />
para modificar cualquiera de sus componentes con el fin de satisfacer la necesidad del esquema del cliente. Puesto que el esquema de direcciones tiene un targetNamespace
que es diferente del que tiene el esquema del cliente, se utiliza el elemento <xs:import />
y, por tanto, la semántica de importación.
El código de ejemplo incluye el esquema de direcciones en los siguientes pasos.
Agrega el esquema del cliente y el esquema de direcciones a un objeto XmlSchemaSet nuevo y luego los compila. Cualquier error y advertencia de validación de esquemas que se encuentre durante la lectura o compilación de los esquemas se controla por medio del delegado ValidationEventHandler.
Recupera los objetos XmlSchema compilados para los esquemas del cliente y de direcciones desde XmlSchemaSet iterando por la propiedad Schemas. Puesto que los esquemas se compilan, las propiedades del conjunto de información posterior a la compilación del esquema son accesibles.
Crea un objeto XmlSchemaImport, establece la propiedad Namespace de la importación en el espacio de nombres del esquema de direcciones, establece la propiedad Schema de la importación en el objeto XmlSchema del esquema de direcciones y agrega la importación a la propiedad Includes del esquema del cliente.
Vuelve a procesar y compilar el objeto XmlSchema modificado del esquema del cliente utilizando los métodos Reprocess y Compile de la clase XmlSchemaSet y lo escribe en la consola.
Por último, escribe de forma recursiva en la consola todos los esquemas importados al esquema del cliente utilizando la propiedad Includes del esquema del cliente. La propiedad Includes proporciona acceso a todas las inclusiones, importaciones o redefiniciones agregadas a un esquema.
A continuación se ofrece el código de ejemplo completo y los esquemas de direcciones y del cliente escritos en la consola.
#using <System.Xml.dll>
using namespace System;
using namespace System::Xml;
using namespace System::Xml::Schema;
ref class XmlSchemaImportExample
{
public:
static void Main()
{
// Add the customer and address schemas to a new XmlSchemaSet and compile them.
// Any schema validation warnings and errors encountered reading or
// compiling the schemas are handled by the ValidationEventHandler delegate.
XmlSchemaSet^ schemaSet = gcnew XmlSchemaSet();
schemaSet->ValidationEventHandler += gcnew ValidationEventHandler(ValidationCallback);
schemaSet->Add("http://www.tempuri.org", "customer.xsd");
schemaSet->Add("http://www.example.com/IPO", "address.xsd");
schemaSet->Compile();
// Retrieve the compiled XmlSchema objects for the customer and
// address schema from the XmlSchemaSet by iterating over
// the Schemas property.
XmlSchema^ customerSchema = nullptr;
XmlSchema^ addressSchema = nullptr;
for each (XmlSchema^ schema in schemaSet->Schemas())
{
if (schema->TargetNamespace == "http://www.tempuri.org")
customerSchema = schema;
else if (schema->TargetNamespace == "http://www.example.com/IPO")
addressSchema = schema;
}
// Create an XmlSchemaImport object, set the Namespace property
// to the namespace of the address schema, the Schema property
// to the address schema, and add it to the Includes property
// of the customer schema.
XmlSchemaImport^ import = gcnew XmlSchemaImport();
import->Namespace = "http://www.example.com/IPO";
import->Schema = addressSchema;
customerSchema->Includes->Add(import);
// Reprocess and compile the modified XmlSchema object
// of the customer schema and write it to the console.
schemaSet->Reprocess(customerSchema);
schemaSet->Compile();
customerSchema->Write(Console::Out);
// Recursively write all of the schemas imported into the
// customer schema to the console using the Includes
// property of the customer schema.
RecurseExternals(customerSchema);
}
static void RecurseExternals(XmlSchema^ schema)
{
for each (XmlSchemaExternal^ external in schema->Includes)
{
if (external->SchemaLocation != nullptr)
{
Console::WriteLine("External SchemaLocation: {0}", external->SchemaLocation);
}
if (external::typeid == XmlSchemaImport::typeid)
{
XmlSchemaImport^ import = dynamic_cast<XmlSchemaImport^>(external);
Console::WriteLine("Imported namespace: {0}", import->Namespace);
}
if (external->Schema != nullptr)
{
external->Schema->Write(Console::Out);
RecurseExternals(external->Schema);
}
}
}
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()
{
XmlSchemaImportExample::Main();
return 0;
}
using System;
using System.Xml;
using System.Xml.Schema;
class XmlSchemaImportExample
{
static void Main(string[] args)
{
// Add the customer and address schemas to a new XmlSchemaSet and compile them.
// Any schema validation warnings and errors encountered reading or
// compiling the schemas are handled by the ValidationEventHandler delegate.
XmlSchemaSet schemaSet = new XmlSchemaSet();
schemaSet.ValidationEventHandler += new ValidationEventHandler(ValidationCallback);
schemaSet.Add("http://www.tempuri.org", "customer.xsd");
schemaSet.Add("http://www.example.com/IPO", "address.xsd");
schemaSet.Compile();
// Retrieve the compiled XmlSchema objects for the customer and
// address schema from the XmlSchemaSet by iterating over
// the Schemas property.
XmlSchema customerSchema = null;
XmlSchema addressSchema = null;
foreach (XmlSchema schema in schemaSet.Schemas())
{
if (schema.TargetNamespace == "http://www.tempuri.org")
customerSchema = schema;
else if (schema.TargetNamespace == "http://www.example.com/IPO")
addressSchema = schema;
}
// Create an XmlSchemaImport object, set the Namespace property
// to the namespace of the address schema, the Schema property
// to the address schema, and add it to the Includes property
// of the customer schema.
XmlSchemaImport import = new XmlSchemaImport();
import.Namespace = "http://www.example.com/IPO";
import.Schema = addressSchema;
customerSchema.Includes.Add(import);
// Reprocess and compile the modified XmlSchema object
// of the customer schema and write it to the console.
schemaSet.Reprocess(customerSchema);
schemaSet.Compile();
customerSchema.Write(Console.Out);
// Recursively write all of the schemas imported into the
// customer schema to the console using the Includes
// property of the customer schema.
RecurseExternals(customerSchema);
}
static void RecurseExternals(XmlSchema schema)
{
foreach (XmlSchemaExternal external in schema.Includes)
{
if (external.SchemaLocation != null)
{
Console.WriteLine("External SchemaLocation: {0}", external.SchemaLocation);
}
if (external is XmlSchemaImport)
{
XmlSchemaImport import = external as XmlSchemaImport;
Console.WriteLine("Imported namespace: {0}", import.Namespace);
}
if (external.Schema != null)
{
external.Schema.Write(Console.Out);
RecurseExternals(external.Schema);
}
}
}
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.Xml
Imports System.Xml.Schema
Class XmlSchemaImportExample
Shared Sub Main()
' Add the customer and address schemas to a new XmlSchemaSet and compile them.
' Any schema validation warnings and errors encountered reading or
' compiling the schemas 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.Add("http://www.example.com/IPO", "address.xsd")
schemaSet.Compile()
' Retrieve the compiled XmlSchema objects for the customer and
' address schema from the XmlSchemaSet by iterating over
' the Schemas property.
Dim customerSchema As XmlSchema = Nothing
Dim addressSchema As XmlSchema = Nothing
For Each schema As XmlSchema In schemaSet.Schemas()
If schema.TargetNamespace = "http://www.tempuri.org" Then
customerSchema = schema
ElseIf schema.TargetNamespace = "http://www.example.com/IPO" Then
addressSchema = schema
End If
Next
' Create an XmlSchemaImport object, set the Namespace property
' to the namespace of the address schema, the Schema property
' to the address schema, and add it to the Includes property
' of the customer schema.
Dim import As XmlSchemaImport = New XmlSchemaImport()
import.Namespace = "http://www.example.com/IPO"
import.Schema = addressSchema
customerSchema.Includes.Add(import)
' Reprocess and compile the modified XmlSchema object
' of the customer schema and write it to the console.
schemaSet.Reprocess(customerSchema)
schemaSet.Compile()
customerSchema.Write(Console.Out)
' Recursively write all of the schemas imported into the
' customer schema to the console using the Includes
' property of the customer schema.
RecurseExternals(customerSchema)
End Sub
Shared Sub RecurseExternals(ByVal schema As XmlSchema)
For Each external As XmlSchemaExternal In Schema.Includes
If Not external.SchemaLocation = Nothing Then
Console.WriteLine("External SchemaLocation: {0}", external.SchemaLocation)
End If
If external.GetType() Is GetType(XmlSchemaImport) Then
Dim import As XmlSchemaImport = CType(external, XmlSchemaImport)
Console.WriteLine("Imported namespace: {0}", import.Namespace)
End If
If Not external.Schema Is Nothing Then
external.Schema.Write(Console.Out)
RecurseExternals(external.Schema)
End If
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
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="http://www.tempuri.org" targetNamespace="http://www.tempuri.org" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://www.example.com/IPO" />
<xs:element name="Customer">
<xs:complexType>
<xs:sequence>
<xs:element name="FirstName" type="xs:string" />
<xs:element name="LastName" type="tns:LastNameType" />
</xs:sequence>
<xs:attribute name="CustomerId" type="xs:positiveInteger" use="required" />
</xs:complexType>
</xs:element>
<xs:simpleType name="LastNameType">
<xs:restriction base="xs:string">
<xs:maxLength value="20" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
<schema targetNamespace="http://www.example.com/IPO" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:ipo="http://www.example.com/IPO">
<annotation>
<documentation xml:lang="en">
Addresses for International Purchase order schema
Copyright 2000 Example.com. All rights reserved.
</documentation>
</annotation>
<complexType name="Address">
<sequence>
<element name="name" type="string"/>
<element name="street" type="string"/>
<element name="city" type="string"/>
</sequence>
</complexType>
<complexType name="USAddress">
<complexContent>
<extension base="ipo:Address">
<sequence>
<element name="state" type="ipo:USState"/>
<element name="zip" type="positiveInteger"/>
</sequence>
</extension>
</complexContent>
</complexType>
<!-- other Address derivations for more countries or regions -->
<simpleType name="USState">
<restriction base="string">
<enumeration value="AK"/>
<enumeration value="AL"/>
<enumeration value="AR"/>
<!-- and so on ... -->
</restriction>
</simpleType>
</schema>
Para obtener más información sobre los elementos <xs:import />
, <xs:include />
y <xs:redefine />
, y sobre las clases XmlSchemaImport, XmlSchemaInclude y XmlSchemaRedefine, vea W3C XML Schema y la documentación de referencia sobre las clases del espacio de nombres System.Xml.Schema.