Практика використання просторів імен XML в проектах, що містять кілька XML-схем, Інші СУБД, Бази даних, статті

Автор: Bладімір Енгельс, Oracle СНД

Введення

При реалізації типових SOA-проектів, як правило, створюється кілька XML-схем. У цих випадках проектувальник XML-схем має вирішити наступне питання:


Який підхід буде більш оптимальний? Яким посібникам потрібно дотримуватися, починаючи роботу над SOA-проектами, в яких створюється кілька XML-схем?

Точності заради, треба зазначити, що є три проектних підходу при роботі з декількома XML-схемами:


  1. гетерогенне простір імен – Кожній XML-схемі присвоюється свій targetNamespace;
  2. гомогенне простір імен – Всім XML-схем присвоюється єдиний targetNamespace;
  3. простір імен типу “хамелеон” – Головної XML-схемі присвоюється targetNamespace, а допоміжним XML-схем не присвоюється ніякого targetNamespace (XML-схеми без targetNamespace використовують targetNamespace головною XML-схеми при об’єднанні як хамелеон).

Для опису та оцінки достоїнств і недоліків трьох зазначених проектних підходів наведемо приклади для кожного з них.

Приклад: XML-модель даних компанії

Уявімо собі проект, який вимагає створення моделі даних компанії, використовуючи XML-схеми. Дана модель створюється у вигляді наступних трьох XML-схем:


Це можна охарактеризувати як “інформація про компанії включає в себе дані по персони і по продукту”. Наведемо три схеми для кожного проектного підходу.

Гетерогенне простір імен

Даний проектний підхід передбачає використання для кожної XML-схеми свого targetNamespace. Нижче наводиться три схеми, спроектовані із застосуванням даного проектного підходу.

Product.xsd

<?xml version=”1.0″?>
<xsd:schema xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
targetNamespace=”http://www.product.org”
xmlns=”http://www.product.org”
elementFormDefault=”unqualified”>
xmlns:per=”http://www.person.org”
xmlns:pro=”http://www.product.org”>
<xsd:complexType name=”ProductType”>
<xsd:sequence>
<xsd:element name=”Type” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

Person.xsd

<?xml version=”1.0″?>
<xsd:schema xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
targetNamespace=”http://www.person.org”
xmlns=”http://www.person.org”
elementFormDefault=”unqualified”>
<xsd:complexType name=”PersonType”>
<xsd:sequence>
<xsd:element name=”Name” type=”xsd:string”/>
<xsd:element name=”SSN” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

Company.xsd

<?xml version=”1.0″?>
<xsd:schema xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
targetNamespace=”http://www.company.org”
xmlns=”http://www.company.org”
elementFormDefault=”unqualified”
xmlns:per=”http://www.person.org”
xmlns:pro=”http://www.product.org”>
<xsd:import namespace=”http://www.person.org”
schemaLocation=”Person.xsd”/>
<xsd:import namespace=”http://www.product.org”
schemaLocation=”Product.xsd”/>
<xsd:element name=”Company”>
<xsd:complexType>
<xsd:sequence>
<xsd:element name=”Person” type=”per:PersonType”
maxOccurs=”unbounded”/>
<xsd:element name=”Product” type=”pro:ProductType”
maxOccurs=”unbounded”/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>

Зверніть увагу, що в схемах використовується три різних простору імен:

http://www.product.org
http://www.person.org
http://www.company.org

Гомогенне простір імен

Даний проектний підхід передбачає використання єдиного targetNamespace для всіх XML-схем. Нижче наводиться три схеми, спроектовані із застосуванням даного проектного підходу.

Product.xsd

<?xml version=”1.0″?>
<xsd:schema xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
targetNamespace=”http://www.company.org”
xmlns=”http://www.product.org”
elementFormDefault=”qualified”>
<xsd:complexType name=”ProductType”>
<xsd:sequence>
<xsd:element name=”Type” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

Person.xsd

<?xml version=”1.0″?>
<xsd:schema xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
targetNamespace=”http://www.company.org”
xmlns=”http://www.person.org”
elementFormDefault=”qualified”>
<xsd:complexType name=”PersonType”>
<xsd:sequence>
<xsd:element name=”Name” type=”xsd:string”/>
<xsd:element name=”SSN” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

Company.xsd

<?xml version=”1.0″?>
<xsd:schema xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
targetNamespace=”http://www.company.org”
xmlns=”http://www.company.org”
elementFormDefault=”qualified”>
<xsd:include schemaLocation=”Person.xsd”/>
<xsd:include schemaLocation=”Product.xsd”/>
<xsd:element name=”Company”>
<xsd:complexType>
<xsd:sequence>
<xsd:element name=”Person” type=”PersonType”
maxOccurs=”unbounded”/>
<xsd:element name=”Product” type=”ProductType”
maxOccurs=”unbounded”/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>

Зверніть увагу, що у всіх трьох схемах використовується єдине просторів імен:

http://www.company.org

Також зверніть увагу, що для об’єднання XML-схем, які використовують єдиний простір імен, застосовується механізм .

Простір імен типу “хамелеон”

Даний проектний підхід передбачає використання targetNamespace тільки для головної XML-схеми, а допоміжним XML-схем не присвоюється ніякого targetNamespace. Нижче наводиться три схеми, спроектовані із застосуванням даного проектного підходу. У даному прикладі XML-схема Company.xsd є головною, XML-схеми Product.xsd і Person.xsd – допоміжні.

Product.xsd (немає targetNamespace)

<?xml version=”1.0″?>
<xsd:schema xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
elementFormDefault=”qualified”>
<xsd:complexType name=”ProductType”>
<xsd:sequence>
<xsd:element name=”Type” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

Person.xsd (немає targetNamespace)

<?xml version=”1.0″?>
<xsd:schema xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
elementFormDefault=”qualified”>
<xsd:complexType name=”PersonType”>
<xsd:sequence>
<xsd:element name=”Name” type=”xsd:string”/>
<xsd:element name=”SSN” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

Company.xsd

<?xml version=”1.0″?>
<xsd:schema xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
targetNamespace=”http://www.company.org”
xmlns=”http://www.company.org”
elementFormDefault=”qualified”>
<xsd:include schemaLocation=”Person.xsd”/>
<xsd:include schemaLocation=”Product.xsd”/>
<xsd:element name=”Company”>
<xsd:complexType>
<xsd:sequence>
<xsd:element name=”Person” type=”PersonType”
maxOccurs=”unbounded”/>
<xsd:element name=”Product” type=”ProductType”
maxOccurs=”unbounded”/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>>

Зверніть увагу на два аспекти при використанні даного проектного підходу:


“Ефект хамелеона …” – Цей термін ввів Генрі Томпсон (Henry Thompson).

Вплив проектних підходів на XML-документи

Вище було продемонстровано, як могли б бути спроектовані XML-схеми з застосуванням трьох проектних підходів. Тепер звернемося до XML-документами. Чи відрізняється створення XML-документів, залежно від застосування того чи іншого проектного підходу? Всі вищенаведені XML-схеми були спроектовані з вимогою явної вказівки просторів імен в XML-документах (на що вказує: elementFormDefault = “qualified”). Якби вони використовували замість цього elementFormDefault = “unqualified”, то XML-документ для всіх трьох випадків мав би наступну форму:

<?xml version=”1.0″?>
<c:Company xmlns:c=”http://www.company.org”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://www.company.org/Company.xsd”>
<Person>
<Name>John Doe</Name>
<SSN>123-45-6789</SSN>
</Person>
<Product>
<Type>Widget</Type>
</Product>
</c:Company>

Як же будуть виглядати XML-документи для наших трьох підходів проектування?

Company.xml (для версії з гетерогенним простором імен в targetNamespace)

<?xml version=”1.0″?>
<Company xmlns=”http://www.company.org”
xmlns:pro=”http://www.product.org”
xmlns:per=”http://www.person.org”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://www.company.org/Company.xsd”>
<Person>
<per:Name>John Doe</per:Name>
<per:SSN>123-45-6789</per:SSN>
</Person>
<Product>
<pro:Type>Widget</pro:Type>
</Product>
</Company>

Зверніть увагу на наступне:


Company.xml (для версії з гомогенним простором імен в targetNamespace)

<?xml version=”1.0″?>
<Company xmlns=”http://www.company.org”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://www.company.org/Company.xsd”>
<Person>
<Name>John Doe</Name>
<SSN>123-45-6789</SSN>
</Person>
<Product>
<Type>Widget</Type>
</Product>
</Company>

Оскільки всі схеми належать одному простору імен, то в XML-документах для даної ситуації можна скористатися перевагою використання простору імен “по-замовчуванню”.

Company.xml (для версії з простором імен типу “хамелеон” в targetNamespace)

<?xml version=”1.0″?>
<Company xmlns=”http://www.company.org”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://www.company.org/Company.xsd”>
<Person>
<Name>John Doe</Name>
<SSN>123-45-6789</SSN>
</Person>
<Product>
<Type>Widget</Type>
</Product>
</Company>

Обидві схеми XML без визначення targetNamespace взяли targetNamespace XML-схеми Company.xsd (подібно хамелеон-ефекту). Таким чином, всі компоненти належать одному targetNamespace, і в XML-документах для даної ситуації також можна скористатися перевагою використання простору імен “по-замовчуванню”.

– застосовуваний лише в гомогенному просторі імен та в просторі імен типу “хамелеон”

Елемент використовується в XML-схемах для отримання доступу до компонентів в інших XML-схемах і одночасно дає можливість внести якесь число (нуль або більше) змін до визначення імпортованих компонентів. Таким чином, елемент виконує подвійну функцію:


Приклад. Розглянемо знову вищенаведену XML-схему Company.xsd. Припустимо, що вона використовує елемент ProductType з Product.xsd. Додатково, під час використання необхідно розширити елемент ProductType і включити в нього елемент ID (ідентифікатор продукту). Наведемо приклад, як це можна зробити, використовуючи елемент :

<?xml version=”1.0″?>
<xsd:schema xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
targetNamespace=”http://www.company.org”
xmlns=”http://www.company.org”
elementFormDefault=”qualified”>
<xsd:include schemaLocation=”Person.xsd”/>
<xsd:redefine schemaLocation=”Product.xsd”>
<xsd:complexType name=”ProductType”>
<xsd:complexContent>
<xsd:extension base=”ProductType>
<xsd:sequence>
<xsd:element name=”ID” type=”xsd:ID”/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:redefine>

<xsd:element name=”Company”>
<xsd:complexType>
<xsd:sequence>
<xsd:element name=”Person” type=”PersonType”
maxOccurs=”unbounded”/>
<xsd:element name=”Product” type=”ProductType”
maxOccurs=”unbounded”/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>

Тепер елемент в XML-документі повинен містити обидва елементи і , тобто:

<?xml version=”1.0″?>
<Company xmlns=”http://www.company.org”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://www.company.org/Company.xsd”>
<Person>
<Name>John Doe</Name>
<SSN>123-45-6789</SSN>
</Person>
<Product>
<Type>Widget</Type>
<ID>1001-01-00</ID>
</Product>
</Company>

Елемент має дуже великий проектної міццю. Правда, використовуватися він може тільки в XML-схемах з єдиним простором імен або в XML-схемах без вказівки простору імен. Таким чином, елемент може бути застосовний тільки проектних підходах з гомогенним простором імен і з простором імен типу “хамелеон”.

Простір імен “по-замовчуванню” і проектний підхід типу “хамелеон”

Якщо XML-схема передбачає використання елемнта в рамках проетного підходу типу “хамелеон” (використовуючи схеми без визначення targetNamespace), то головна схема повинна оголошувати простір імен з targetNamespace також як простір імен “по-замовчуванню”.

Як уникнути колізії імен при використанні підходу типу “хамелеон”

Колізія імен

Коли головна XML-схема використовує хамелеон-комоненти, то ці компоненти стають частиною простору імен (зазначеного в targetNamespace) головною XML-схеми, так наче проектувальник XML-схеми використовував in-line декларацію елементів і типів. Якщо головна схема включає () кілька XML-схем без вказівки простору імен, то існує шанс, що виникне колізія імен. Таким чином, головна XML-схема не зможе використовувати деякі компоненти допоміжних XML-схем (в яких не зазначено простір імен), оскільки для них має місце колізія імен з елементами з інших допоміжних XML-схем. Для демонстрації проблеми колізії імен, розглянемо наступний приклад.

Припустимо, існує дві схеми XML без вказівки targetNamespace:

1.xsd
A
B
2.xsd
A
C

XML-схема 1.xsd визначає елементи A і B без вказівки простору імен.
XML-схема 2.xsd визначає елементи A і C без вказівки простору імен.
Тепер, якщо XML-схема 3.xsd включає в себе () дві зазначені XML-схеми без вказівки простору імен, виникає колізія імен для елемента A, оскільки його оголошено два рази:

3.xsd
targetNamespace=”http://www.example.org”
<include schemaLocation=”1.xsd”/>
<include schemaLocation=”2.xsd”/>

Зверніть увагу, що помилкою не є існування визначення двох елементів з однаковим ім’ям, якщо вони належать до одного типу. Якщо ж вони належать різним типам, то це помилка, і має місце колізія імен.

Стандартним механізмом виключення колізій імен як раз і є застосування просторів імен. Якщо б у наведеному вище прикладі компоненти XML-схем 1.xsd і 2.xsd знаходилися б в різних просторах імен і вони були б імпортовані в XML-схему 3.xsd, то колізії імен не виникло. [Зауважте, що два компоненти можуть мати однакове ім’я, якщо компоненти належать різним просторів імен.]

А як же вирішити проблему колізії імен при використанні просторів імен типу “хамелеон”?

Вирішення проблеми колізії імен із застосуванням проксірующіх XML-схем

Існує дуже просте рішення даної проблеми колізії імен: для кожної включаемой XML-схеми без вказівки простору імен створюється допоміжна проксірующая XML-схема, в якій задекларовано простір імен і яка сама вже включає () допоміжні XML-схеми без вказівки просторів імен. Потім головна схема просто імпортує () все проксірующіе XML-схеми.

Наведемо приклад демонструє даний проектний підхід:


1-proxy.xsd
targetNamespace=”http://www.1-proxy.org”
<xsd:include schemaLocation=”1.xsd”/>

2-proxy.xsd
targetNamespace=”http://www.2-proxy.org”
<xsd:include schemaLocation=”2.xsd”/>

main.xsd
targetNamespace=”http://www.main.org”
<xsd:import namespace=”http://www.1-proxy.org”
schemaLocation=”1-proxy.xsd”/>
<xsd:import namespace=”http://www.2-proxy.org”
schemaLocation=”2-proxy.xsd”/>

Застосовуючи даний проектний підхід, нам вдалося уникнути колізії імен. Більш того, у цього проектного підходу є ще одне додаткове перевага: в рамках проксірующіх XML-схем також можна використовувати елемент для внесення зміни в хамелеон-компоненти.

Таким чином, даний проектний підхід регламентує триступеневий процес:


Використання даного трехступенчатого процесу дозволяє більш гнучко приймати рішення в проекті з приводу доменів (просторів імен) тих компонентів, які використовуються повторно. Більше того, з’являється можливість внести зміни в хамелеон-компоненти. Хоча в даному підході і використовується додатковий крок процесу (створення проксірующіх XML-схем), все ж він має велику гнучкість.

Порівняємо даний триступеневий процес з раніше описаним двоступінчастим процесом, в якому компонентам призначаються простору імен з самого початку існування компонента:

1-fixed.xsd
targetNamespace=”http://www.1-fixed.org”
A
B
2-fixed.xsd
targetNamespace=”http://www.2-fixed.org”
A
C
main.xsd
targetNamespace=”http://www.main.org”
<xsd:import namespace=”http://www.1-fixed.org”
schemaLocation=”1-fixed.xsd”/>
<xsd:import namespace=”http://www.2-fixed.org”
schemaLocation=”2-fixed.xsd”/>

Двоступінчастий процес дає той же результат, що і триступеневий. У даному прикладі компоненти вже не є “хамелеонами”, і елементи A, B і C жорстка прив’язаність до відповідних просторів імен з початку життєвого циклу компонентів. Зворотний бік даного підходу – якщо в main.xsd знадобиться внести зміни до визначення компонентів з використанням , то це буде неможливо. Крім того, проектувальник головною XML-схеми змушений використовувати простору імен, визначені кимось іншим. Ці компоненти є статичними, незмінними і з фіксованим простором імен.

Засоби, що полегшують використання хамелеон-компонентів

Опис проблеми ідентифікації хамелеон-компонентів

Ми вже кілька разів спостерігали, що хамелеон-компоненти можуть змішуватися в схемах, які їх використовують. Це відбувається, коли вони приймають простір імен включають () їх XML-схем. Якими ж засобами можна ідентифікувати компоненти, які мають багато уявлень, що відносяться до різних просторів імен?

Припустимо, існують наступні XML-схеми без визначення просторів імен:

1.xsd
A
B

Далі ми визначаємо головну XML-схему main.xsd, яка включає () допоміжну XML-схему “хамелеон” 1.xsd, а також сама містить визначення елемента з іменем A (оскільки він знаходиться в іншому символьному оточенні – всередині елемента , це не призведе до колізії імен).

main.xsd
targetNamespace=”http://www.example.org”
<include schemaLocation=”1.xsd”/>
<element name=”stuff”>
<complexType>
<sequence>
<element name=”A” type=”xxx”/>

</sequence>
</complexType>
</element>

Припустимо, в процесі трансформації нам необхідно чітко ідентифікувати хамелеон-компонент A, незалежно від того, до якого простору імен вони, можливо, будуть належати в майбутньому. Як нам відрізнити хамелеон-компонент A від локально визначеного в XML-схемі компонента A?


Ідентифікація хамелеон-компонентів

Існує одне просте засіб – при створенні хамелеон-компонента призначити йому глобально унікальний ідентифікатор (GUID). Специфікація XML Schema дозволяє додавати атрибут id для елемента, атрибута, а також для компонентів простого і комплексного типів. Зверніть увагу, що атрибут id виключно локальний для XML-схеми, і він ніколи не потрапляє в XML-документ. Саме цей атрибут можна використовувати для точної ідентифікації хамелеон-компонента, незалежно від його поточного простору імен.

Питання: що станеться, якщо через проблеми мережі, XML-процесор не зможе отримати доступ до XML-схемою, яка містить необхідні визначення?

Як і у випадку з DTD-визначеннями відбудеться виняткова ситуація в XML-процесорі. Рішення даної проблеми – завжди зберігати копії використовуваних XML-схем локально.


Практика використання просторів імен XML в проектах

Вище були описані проектні підходи стосовно використання просторів імен XML в проектах. Були розглянуті як XML-схеми, так і XML-документи для кожного з трьох проектних підходів.

Тепер залишилося відповісти на головне питання: який підхід краще, і в якому випадку?

Якщо в проекті використовується XML-схема, створена і контрольована кимось іншим, то необхідно використовувати імпортування () даної XML-схеми, тобто використовувати проектний підхід з гетерогенним простором імен. Копіювати такі компоненти в простір імен проекту – не дуже вдала ідея з двох причин:


Більш цікава ситуація (ситуація, яка розглядалася в якості прикладів), як вчинити з простором імен XML-схем, що створюються в рамках проекту і повністю підконтрольних одному проектувальнику (Або групі). Нижче наведено кілька рекомендацій:

Використовуйте простір імен типу “хамелеон”:


  • з XML-схемами, які містять компоненти, які не мають спадкової семантикою самі по собі;
  • з XML-схемами, які містять компоненти, які володіють семантикою тільки в контесті головною XML-схеми;
  • коли немає бажання жорстко призначати простір імен для XML-схеми, щоб мати можливість призначати проектованим компонентам спецефические простір імен того додатка, в якому вони будуть використані.

      Приклад. Репозиторій таких компонентів як, наприклад, XML-схема, яка визначає типи масиву, вектора, пов’язаного списку і т. п., повинні визначатися без вказівки targetNamespace (тобто як хамелеон-XML-схема).

      Якщо XML-схема містить тільки визначення типів (відсутні декларації елементів), то вона також хороший кандидат на використання хамелеон-простору імен.


      Використовуйте гомогенне простір імен:



      • якщо все XML-схеми концептуально співвідносяться один з одним;
      • якщо немає необхідності візуально ідентифікувати в XML-документі приналежність елементів і атрибутів тієї чи іншої XML-схемі. При цьому підході всі компоненти належать одному простору імен і, таким чином, втрачається можливість ідентифікувати в XML-документі, що “елемент A визначений у схемі X”. Часто це нормально, що проектувальник не бажає категорізовивать роздільно елементи або атрибути. В І тут гомогенне простір імен цілком підходить.

      Використовуйте гетерогенне простір імен:


    • коли є кілька елементів з однаковим ім’ям (з метою запобігти колізію імен);
    • якщо є необхідність візуально ідентифікувати в XML-документі приналежність елементів і атрибутів тієї чи іншої XML-схемі. При цьому підході компоненти належать різним просторів імен, і, таким чином, існує можливість ідентифікувати в XML-документі, що “елемент A визначений у схемі X”.

        І, нарешті, як було продемонстровано вище, в XML-схемах кожен компонент може бути унікально ідентифікований з використанням атрибута id (це не те ж саме, що оголосити атрибут id для елемента; це внутрішній механізм XML-схем для ідентифікації кожного компонента XML-схеми). Використання атрибута id для ідентифікації кожного компонента XML-схеми дає навіть більший контроль над компонентом, ніж при використанні просторів імен. Комбінація цих двох засобів – просторів імен та атрибутів id компонентів XML-схем – потужний тандем, що дозволяє надійно ідентифікувати комоненти XML-схем, як візуально, так і програмно.

      • Схожі статті:


        Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

        Коментарів поки що немає.

        Ваш отзыв

        Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

        *

        *