Поделиться через


Включение или импорт 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 /> и семантика импорта.

Пример кода включает пользовательскую схему со следующими шагами.

  1. Добавление пользовательской схемы и схемы адресов в новый объект XmlSchemaSet и компиляция схем. Все предупреждения и ошибки проверки схемы, обнаруженные в процессе чтения или компиляции, обрабатываются делегатом ValidationEventHandler.

  2. Получение скомпилированных объектов XmlSchema для пользовательской схемы и схемы адресов из XmlSchemaSet путем прохода по свойству Schemas. Так как схемы скомпилированы, доступны свойства информационного набора PSCI.

  3. Создание объекта XmlSchemaImport, задание в свойстве импорта Namespace пространства имен схемы адресов, задание в свойстве импорта Schema объекта XmlSchema схемы адресов и добавление импорта в свойство Includes пользовательской схемы.

  4. Повторная обработка и компиляция измененного объекта XmlSchema с помощью методов Reprocess и Compile класса XmlSchemaSet и последующая запись объекта в консоль.

  5. Заключительный шаг — рекурсивная запись всех схем, импортированных в пользовательскую схему, в консоль с помощью свойства Includes пользовательской схемы. Свойство Includes предоставляет доступ ко всем объектам, добавленным в схему путем включения, импорта или переопределения.

Далее приведен полный пример кода, а также пользовательская схема и схема адресов, записанные в консоль.

Imports System
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
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);
    }
}
#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;
}
<?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 Schema и в справочной документации по классу пространства имен System.Xml.Schema.

См. также

Основные понятия

Общие сведения об модели объектов XML-схемы

Чтение и запись XML-схем

Построение XML-схем

Обход XML-схем

Изменение XML-схем

XmlSchemaSet для компиляции схемы