Включение или импорт XML-схем
Схема XML может содержать элементы <xs:import />
, <xs:include />
и <xs:redefine />
. Эти элементы схемы ссылаются на другие схемы XML, которые можно использовать в дополнение к структуре схемы, их включающей или импортирующей. Классы XmlSchemaImport, XmlSchemaInclude и XmlSchemaRedefine сопоставляются с этими элементами в API модели SOM.
Включение или импорт схемы XML
В следующем примере кода пользовательская схема XML дополняется схемой адресов. Добавление к пользовательской схеме схемы адресов делает типы адресов доступными в пользовательской схеме.
Схему адресов можно добавить с помощью элементов <xs:include />
или <xs:import />
, использующих компоненты схемы адресов без изменения, или с помощью элемента <xs:redefine />
, который изменяет компоненты схемы в соответствии с задачами пользовательской схемы. Поскольку схема адресов имеет пространство имен targetNamespace
, которое отличается от пользовательской схемы, используется элемент <xs:import />
и семантика импорта.
Пример кода включает пользовательскую схему со следующими шагами.
Добавление пользовательской схемы и схемы адресов в новый объект XmlSchemaSet и компиляция схем. Все предупреждения и ошибки проверки схемы, обнаруженные в процессе чтения или компиляции, обрабатываются делегатом ValidationEventHandler.
Получение скомпилированных объектов XmlSchema для пользовательской схемы и схемы адресов из XmlSchemaSet путем прохода по свойству Schemas. Так как схемы скомпилированы, доступны свойства информационного набора PSCI.
Создание объекта XmlSchemaImport, задание в свойстве импорта Namespace пространства имен схемы адресов, задание в свойстве импорта Schema объекта XmlSchema схемы адресов и добавление импорта в свойство Includes пользовательской схемы.
Повторная обработка и компиляция измененного объекта XmlSchema с помощью методов Reprocess и Compile класса XmlSchemaSet и последующая запись объекта в консоль.
Заключительный шаг - рекурсивная запись всех схем, импортированных в пользовательскую схему, в консоль с помощью свойства Includes пользовательской схемы. Свойство Includes предоставляет доступ ко всем объектам, добавленным в схему путем включения, импорта или переопределения.
Далее приведен полный пример кода, а также пользовательская схема и схема адресов, записанные в консоль.
#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>
Дополнительные сведения об элементах <xs:import />
, <xs:include />
и <xs:redefine />
, а также классах XmlSchemaImport, XmlSchemaInclude и XmlSchemaRedefine см. в документации консорциума W3C по схемам XML и в справочной документации по классу пространства имен System.Xml.Schema.