xmlhack.ru logo
>> статьи на xmlhack.ru

Управление версиями XML-словарей

Автор: Дэвид Орчард
Опубликовано на XML.com (03.12.2003, англ.): http://www.xml.com/pub/a/2003/12/03/versioning.html
Опубликовано на Intersoft Lab (03.12.2003, рус.): http://www.iso.ru/journal/articles/301.html
Опубликовано на xmlhack.ru (15.02.2004, рус.): http://xmlhack.ru/texts/04/version.management/version.management.html
В закладки:   Del.icio.us   reddit

Введение

Язык XML предназначен для создания языков, основанных на самодокументированной разметке. Неизбежное развитие этих языков называется управлением версиями. Управление версиями подразумевает добавление, удаление или изменение частей языка. На практике управление версиями — это чрезвычайно сложная задача в теории вычислительной техники, имеющая длинную историю безуспешных проб и ошибок. Можно утверждать, что одна из причин невероятного роста популярности «Всемирной паутины» заключается в том, что развитие языков и управление версиями были встроены в заголовки HTML и HTTP, каждый из которых предоставляет явные точки и правила расширяемости, необходимые для понимания расширений, сделавших возможным их децентрализованное расширение и управление версиями.

Спецификация «Пространства имён XML» обеспечивает идеальный механизм идентификации версий языков, и все языки XML-схемы — такие как W3C XML Schema — предусматривают управляемую расширяемость.

В этой статье описываются подходы, позволяющие добиться более эффективной слабой связи между системами за счёт расширения возможности вносить изменения, обеспечивающие обратную и прямую совместимость (backwards- and forwards-compatible changes) при развитии связанных систем. Эти приёмы предназначены для совместимых изменений как при передаче схемы, так и без её распространения. Для управления версиями XML-словарей определяется набор правил, в которых используются конструкции спецификаций «Пространства имён XML» и «XML Schema». Этот набор включает правила для работы с языками, которые предоставляют расширяемую модель контейнера, особенно SOAP. Этот совокупный набор правил называется моделью расширяемости «Обязательно игнорировать» («Must Ignore» pattern). Как ни странно, но несмотря на то, что эта модель в значительной степени способствовала признанию тегов HTML и заголовков HTTP, среди практиков-разработчиков XML-приложений она не снискала широкую популярность. Данная статья призвана исправить эту ситуацию в отношении существующих программных оболочек, предназначенных для проверки допустимости документов по схеме. В последующих материалах будут рассмотрены оболочки, в которых реализуется более новый подход к проверке допустимости — нестрогая проверка.

Определение совместимости

Определения обратной и прямой совместимости можно найти в Бесплатном он-лайн словаре по вычислительной технике FOLDOC [1]. В этой статье эти определения переосмысливаются с позиции инициатора сообщений, а именно: отправителей и получателей, а не клиентов и серверов. Итак, обратная совместимость означает, что при установке новой версии получателя существующая версия отправителя не будет разрушена. Другими словами, отправитель посылая старую версию сообщения получателю, который понимает новую версию, может быть уверен, что его сообщение успешно обработано. Прямая совместимость означает, что более старая версия получателя может использовать более новые сообщения и при этом не останавливаться. Разумеется, эта более старая версия не реализует новое поведение, но отправитель может посылать более новую версию сообщения, и это сообщение будет успешно обработано.

Другими словами, обратная совместимость подразумевает, что существующие отправители могут использовать сервисы, которые были модернизированы, а прямая совместимость означает, что более новые отправители могут продолжать использовать существующие сервисы.

Изменения, поддерживающие прямую совместимость, обычно приводят к добавлению необязательных элемент(ов) и/или атрибут(ов). Цена внесения изменений, которые не обеспечивают обратную или прямую совместимость, зачастую очень высока, обычно для того, чтобы адаптировать программный продукт к новой версии, необходимо провести его модернизацию. Правила, описанные ниже, оптимизированы для изменений, согласующихся с обратной и прямой совместимостью. В этой статье доказывается, что это не означает изменения имени пространства имён или имён элементов.

Хотя совместимость определяется для отправителя и получателя отдельного сообщения, в большинстве спецификаций Web-сервисов содержатся определения входных и выходных данных. В соответствии с этими определениями, Web-сервис, который усовершенствует свою выходную схему, считается новым получателем. В результате при применении определений совместимости к выходным сообщениям пара терминов отправитель/получатель для входных сообщений меняется местами. Если получатель модернизирует схему выходного сообщения, то он «отправляет» более новую версию сообщения, и, следовательно, он считается «отправителем».

Идентификация и расширение языков

Встраивание расширяемости в языки обычно приводит к системам, которые являются более свободно связанными. Расширяемость позволяет отправителям изменять экземпляры без необходимости следовать централизованным нормативам. Таким образом, первое правило, касающееся расширяемости — это:

1. Правило «Расширяемость допускается»: языки ДОЛЖНЫ быть предназначены для расширяемости

Основное требование, предъявляемое к расширяемости, это возможность определять язык, состоящий из элементов и атрибутов. Пространства имён XML обеспечивают технологию связывания URI (Uniform Resource Identifier, универсальный идентификатор ресурса) c именем XML-элемента или атрибута, то есть задают язык этого имени. В результате, также удаётся избежать конфликта имён.

Спецификация «W3C XML Schema» предоставляет конструкцию, называемую групповой символ (wildcard), <xs:any>, позволяющую проверять, где допускаются элементы из определённого пространства имён. Групповой символ означает, что элементы в указанном пространстве имён допустимы в реальных документах там, где находится групповой символ. Благодаря этому можно чётко определять расширения схем. Получатели расширенных документов могут устанавливать и, в зависимости от модели обработки расширений, без риска игнорировать расширения, которые они не понимают.

<xs:any> использует атрибут namespace, чтобы проверять, из каких пространств имён поступают элементы расширения. Основные значения этого атрибута — ##any, которое означает, что схему можно расширить, используя элемент из любого возможного пространства имён; ##other, который допускает только элементы расширения из пространств имён, отличных от текущего; ##targetnamespace, допускает только элементы расширения из текущего пространства имён.

<xs:any> использует атрибут processContents, чтобы контролировать, как XML-парсер проверяет на допустимость расширенные элементы. Возможные методы: «lax» («нестрогий») — допускающий проверку, «strict» («строгий») — требующий проверки, «skip» («пропустить») — позволяющий её пропустить. В этой статье используется нестрогая проверка, поскольку это наиболее гибкий и типичный выбор для спецификаций Web-сервисов.

Основная цель модели «Необходимо пропускать» — разрешить внесение в документы изменений, обеспечивающих обратную и прямую совместимость. Как минимум, это не подразумевает ни добавления имён пространств имён, ни изменения имён элементов. Добавление имён элементов в целевое пространство имён (target namespace) может быть выполнено с пространством имён ##any или комбинацией пространства имён ##other и целевого пространства имён словаря.

Приведём ряд примеров, демонстрирующих это правило. Предположим, что заказ на поставку (purchase order) пересылается с одной машины на другую. В результате обработки этого заказа появляется сообщение «отгружено» («shipped»). Однако, это сообщение могло быть отправлено спустя какое-то время после получения заказ на поставку. Было бы желательно, чтобы программное обеспечение, осуществляющее отправку, могло бы подождать ответ произвольное время (синхронный обмен сообщениями). Предпочтительная модель для получателя — иметь возможность самостоятельно отправить сообщение «отгружено», не заставляя отправителя ждать. Получатель «перезванивает» первоначальному отправителю — отсюда происходит термин «обратный вызов» («callback»). Отправитель предоставляет получателю адрес в виде адреса обратного вызова. Он указывает адрес, который получатель должен использовать для отправки отправителю любых последующих сообщений. В случае Web-сервисов этот обратный вызов обычно отравляется в виде блока SOAP Header.

Предпочтительным вариантом было бы применение расширяемого стиля ##any. Ниже приведён тип CallbackType (тип обратного вызова), который использует эту модель:

<s:complexType name="CallbackType">
 <s:sequence>
 <s:element name="callbackLocation" type="s:anyURI" 
  minOccurs="1" maxOccurs="1"/>
 <s:any processContents="lax" minOccurs="0" 
  maxOccurs="unbounded" namespace="##any"/>
 </s:sequence>
 <s:anyAttribute/>
</s:complexType>

Пример 1. Схема, в которой для расширяемости используется ##any

Однако, функционированию этой модели препятствуют описанные ниже детерминистических ограничения XML-схемы W3C. Проблема возникает при добавлении необязательного элемента в последующую версию обратного вызова. В качестве примера можно привести время простоя. Время простоя обратного вызова — это ценная информация для получателя. Либо получатели могут продолжить обработку, если они не понимают время простоя. Приведённая ниже схема — это приблизительно то, что желательно создать для использования групповых символов, но она неправомерна из-за детерминистических ограничений:

<s:complexType name="CallbackType">
 <s:sequence>
 <s:element name="callbackLocation" type="s:anyURI" 
  minOccurs="1" maxOccurs="1"/>
 <s:element name="expires" type="s:dateTime" 
  minOccurs="0" maxOccurs="1"/>
 <s:any processContents="lax" minOccurs="0" 
  maxOccurs="unbounded" namespace="##any"/>
 </s:sequence>
 <s:anyAttribute/>
</s:complexType>

Пример 2. Неправомерная схема

Поскольку эта модель не работает, требуется создание модели схемы, которая является грубым эквивалентом, необходимым для достижения первоначальной цели. Чтобы разрешить новые расширения в том же самом пространстве имён, разработчик схемы должен создать тип расширения, который разрешает расширения в том же пространстве имён. Чтобы разрешить надлежащее управление версиями определений языка XML, необходимы ещё два правила: первое — для пространства имён:

2. Правило «Любое пространство имён»: уровень расширяемости ДОЛЖЕН предусматривать расширения в любом пространстве имён. Для приложений XML-схемы точка расширяемости ДОЛЖНА быть элементом, который разрешает расширение в целевом пространстве имён, и групповым символом, который разрешает расширения в любом другом пространстве имён.

Второе правило — допущение расширяемости:

3. Правило «Полная расширяемость»: . все XML-элементы ДОЛЖНЫ разрешать расширяемость элемента после определения элемента и допускать любые атрибуты.

Ниже приведён пример типа Callbacktype, который выполняет эти требования:

<s:complexType name="CallbackType">
 <s:sequence>
 <s:element name="callbackLocation" type="s:anyURI" 
  minOccurs="1" maxOccurs="1"/>
 <s:element name="Extension" type="wscb:ExtensionType" 
  minOccurs="0" maxOccurs="1"/>
 <s:any processContents="lax" minOccurs="0" 
  maxOccurs="unbounded" namespace="##other"/>
 </s:sequence>
 <s:anyAttribute/>
</s:complexType>
<s:complexType name="ExtensionType">
 <s:sequence>
 <s:any processContents="lax" minOccurs="1" 
  maxOccurs="unbounded" namespace="##targetnamespace"/>
 </s:sequence>
 <s:anyAttribute/>
 </s:complexType>

Пример 3. Тип Callback с расширяемостью

Поскольку каждое расширение в целевом пространстве имён находится внутри элемента Extension, каждое последующее пространство имён будет увеличивать вложенность на один уровень. Хотя такой уровень вложенности на расширение нежелателен, это то, что сегодня можно сделать при задании строгой проверки на допустимость по XML-схеме W3C. Кажется, что наличие многочисленных вложенных элементов оправдано, если в язык могут быть внесены многократные совместимые исправления. Этот приём позволяет выполнить проверку допустимости расширений в целевом пространстве имён при сохранении проверки допустимости самого целевого пространства имён.

В общем расширение может быть определено с помощью новой спецификации, в которой указывается нормативная ссылка на более раннюю спецификацию, а затем определяется новый элемент. На самом деле основной смысл в проектировании пространств имён XML — разрешить децентрализованные расширения. Неизбежным следствием является необходимость получения разрешения для расширений в том же пространстве имён. У пространства имён есть владелец, поэтому изменение смысла чего-либо не владельцами пространства имён может привести к нежелательным результатам.

Понимание расширений

В идеале отправители должны уметь расширять существующие XML-документы новыми элементами, не вынуждая при этом получателей изменять существующие реализации. Расширяемость — первый шаг на пути достижения этой цели, но для обеспечения совместимости также требуется модель обработки расширений. Поведение программного обеспечения при его взаимодействии с расширением должно быть чётким. Таким образом, можно задать следующее правило:

4. Правило «Обеспечение модели обработки»: языки ДОЛЖНЫ устанавливать модель обработки для взаимодействия с расширениями.

Самая простая модель обработки, которая реализует совместимые изменения, заключается в игнорировании содержания, которое непонятно. Ниже приведено соответствующее правило:

5. Правило «Обязательно игнорировать»: получатели документа ОБЯЗАНЫ игнорировать любые XML-атрибуты и элементы в допустимом XML-документе, которые они не распознают.

Это правило не требует, чтобы элементы были физически удалены — они должны быть только пропущены при обработке. У правила «Обязательно игнорировать» длинные исторические корни. HTML 1.1, 2.0 и 3.2 следуют этому правилу; в этих языках установлено, что любой неизвестный начальный или конечный тег не отображается во процессе преобразования в символы. В HTTP 1.1 [6] указано, что получатель должен пропускать любой заголовок, который он не понимает: «Нераспознанные поля заголовков ДОЛЖНЫ быть пропущены получателем и ОБЯЗАНЫ быть пересланы прозрачными представителями (proxy)». Впервые правило «Обязательно игнорировать» появилось в 1997г., оно было введено рабочей группой WebDAV [19] в разделе 14 спецификации RFC 2518 [5] (Запрос на комментарии), а затем опубликовано отдельным документов — «Гибкий профиль обработки XML-документов» (Flexible XML Processing Profile [2]).

С обработкой расширений связаны два больших типа словарей. Эти типы являются приложениями (документами), ориентированными на данные и предназначенными для презентации. Для ориентированных на данные приложений, таких как Web-сервисы, это правило имеет следующий вид:

6. Правило «Обязательно игнорировать всё»: правило «Обязательно игнорировать» применяется к нераспознанным элементам и их потомкам.

Например, если сообщение получено с нераспознанными элементами в блоке SOAP header, они должны быть пропущены, если только не помечены как «mustUnderstand» (см. ниже правило 10), однако допустимо предположить, что нераспознанные элементы могут быть записаны в лог-файл.

Возможно, что для словарей, ориентированных на документы, необходимо другое правило, поскольку приложение обычно пытается представить содержание неизвестного элемента. Ниже приведено правило для приложений, ориентированных на документы:

7. Правило «Обязательно игнорировать контейнер»: правило «Обязательно игнорировать» применяется только к нераспознанным элементам.

В результате потомки элементов сохраняются, например, с целью отображения.

Вместо игнорирования нераспознанных элементов язык может обеспечить иную модель для обработки расширений. Такая модель может заключаться в том, что получатель генерирует ошибку, если он обнаруживает компонент, который не понимает. В качестве примера можно привести спецификацию безопасности, согласно которой получатель должен понимать любое расширение. Для этого случая характерен существенный недостаток, поскольку внесение совместимых изменений в язык не допускается, а такие изменения не могут быть проигнорированы. Ещё одна модель — это модель нейтрализация неисправности (fallback), в которой в случае, если получатель не понимает расширения, предлагается альтернативные элементы. XSLT 2.0 обеспечивает такую модель.

Управление версиями

Если требуется новая версия языка, и она обратно совместима с более старым языком, разработчик схем должен принять решение об имени пространства имён для имён в новом языке. В этом случае имеется два варианта: создать новое имя пространства имён или воспользоваться существующим. По нашему мнению, повторное использование более результативно, но мы рассмотрим и выбор №1 в разделе «новое пространство имён». Правило для повторного использования пространств имён может быть сформулировано следующим образом:

8. Правило «Повторного использования имён пространств имён»: если в спецификацию могут быть внесены изменения, обеспечивающие обратную совместимость, НЕОБХОДИМО использовать старое имя пространства имён вместе с моделью расширения XML.

Отсюда можно сделать важный вывод о том, что новое имя пространств имён необходимо только тогда, когда внесено несовместимое изменение.

9. Правило «Повторного использования пространств имён»: новое имя пространства имён используется, если обратная совместимость недопустима, то есть программное обеспечение ОБЯЗАНО приостановиться, если оно не понимает новые конструкции языка.

Изменения, не поддерживающие обратную совместимость, обычно возникают в следующих двух ситуациях: при добавлении требуемой информационной единицы или изменении семантики существующей информационной единицы.

Приведённое выше правило требует соблюдения правил «Обязательно игнорировать» и «Любое пространство имён». Если требования этих правил не выполнены, разработчик языка оказывается лишённым возможности вносить совместимые изменения и повторно использовать имя пространства имён.

Выше отмечалось, что повторное использование имён пространств имён для совместимых расширений — хорошая практика. Противоположенный подход состоит в том, что владелец пространства имён мог бы использовать новое имя для совместимых изменений, предоставив точки расширяемости, допускающие другие пространства имён — xs:any namespace="##other". Этот подход проблематичен — расширение в другом пространстве имён означает, что комбинированная схема не может быть проверена полностью. Точнее, невозможно создать новую схему, которая ограничивает групповой символ. Предположим, например, что ns1 содержит foo и bar. В этом случае просто используя ограничения XML-схемы W3C, невозможно взяв схему SOAP — пример схемы с групповым символом — потребовать, чтобы элемент ns1:foo был бы потомком элемента заголовка, а ns1:bar не был бы потомком элемента заголовка. Действительно, потребность в такой возможности «взывает» к функциональности WSDL (Web Services Description Language, язык описания Web сервисов). Применение подхода с новым именем пространства имён имеет своим результатом спецификации и пространства имён, которые расчленены неподходящим образом, поскольку связанные конструкции оказываются в различных пространствах имён. Далее, повторное использование одного и того же пространства имён гарантирует лучшую инструментальную поддержку. Многие приложения используют одну схему для создания эквивалентных программных конструкций. Эти инструменты часто работают наилучшим образом с поддержкой одиночного пространства имён для «обобщённых» конструкций. Повторное использование имени пространства имён разрешает по крайней мере автору пространства имён вносить изменения в пространства имён и выполнять проверку допустимости расширений.

Замещение модели обработки по умолчанию

В случае соблюдения правила «Обязательно пропускать», часто может возникнуть ситуация, при которой разработчик расширения захочет потребовать, чтобы получатель понимал расширение, замещая правило «Обязательно пропускать» следующим правилом:

10. Правило «Обеспечение mustUnderstand»: языки контейнера должны обеспечить модель «mustUnderstand» для обработки факультативности расширений, которые замещают правило «Обязательно пропускать».

Это правило и правило «Обязательно пропускать» работают совместно, обеспечивая стабильную и гибкую модель обработки расширений. Можно доказать, что наиболее простой и гибкий приём замещения — это признак mustUnderstand, который указывает, должна ли единица быть понятной. Атрибуты для SOAP [7], WSDL [8] WS-Policy [10] и значения для установления understand имеют следующий вид: soap:mustUnderstand="1", wsdl:required="1", wsp:Usage="wsp:Required", соответственно. SOAP, вероятно, наиболее общий случай контейнера, который обеспечивает модель mustUnderstand. Значение по умолчанию равно 0, что фактически является правилом «Обязательно пропускать».

Признак mustUnderstand позволяет отправителю вставлять расширения в контейнер и использовать атрибут mustUnderstand для замещения правила «Обязательно пропускать». Благодаря этому отправители могут расширять сообщения, не меняя пространство имён родителя элемента расширения и поддерживая обратную совместимость. Очевидно, получатель должен быть расширен, чтобы обрабатывать новые расширения, хотя теперь между моделью обработки языка и моделью обработки расширения появляется слабая связь.

Кроме того, возможны и другие подходы, как, например, предоставление элемента, который указывает, какие пространства имён расширения должны быть понятны.

В некоторых случаях язык не предоставляет механизм mustUnderstand. При отсутствии модели mustUnderstand невозможно заставить получателей отклонить сообщение, если они не понимают пространство имён расширения.

Детерминизм

У определений типа документа (DTD, Document Type Definition) и XML-схемы W3C есть правило, согласно которому схемы должны иметь детерминистические модели содержания. Так, в спецификации «XML 1.0» записано:

Например, модель содержания ((b, c) | (b, d)) не является детерминистической, поскольку, принимая во внимание начальное b, XML-процессор, не проверив, какой элемент следует за b, не может знать, какая b в модели содержания сопоставляется.

Использование ##any означает, что имеются схемы, которые хотелось бы составить, но которые не являются допустимыми.

11. Правило «Детерминизм»: использование групповых символов ОБЯЗАНО быть детерминистическим. Расположение групповых символов, пространство имён расширений групповых символов, значения minOccurs и maxOccurs являются ограниченными, а ограничения типов контролируемыми.

Как было показано выше, обычный подход проектирования — обеспечить точку расширяемости (не элемент), разрешив любое пространство имён в конце типа. Это обычно выполняется с помощью xs:any namespace="##any".

Во многих случаях, как и с законченным решением, в ситуации с детерминизмом это невыполнимо. Во-первых, точка расширяемости может иметь место только после обязательного элемента в исходной схеме, ограничивая тем самым область расширяемости исходной схемы. Во-вторых, изменения, поддерживающие обратную совместимость, требуют, чтобы добавленный элемент был необязательным, что подразумевает minOccurs="0". Детерминизм не позволяет разместить minOccurs="0" перед точкой расширяемости ##any. Таким образом, при добавлении элемента в точке расширяемости разработчик схемы может задать элемент необязательным и потерять точку расширяемости или же определить его как обязательный, но лишиться обратной совместимости.

Причины сложностей

Выше были показаны сложности использования XML и XML-схемы W3C для получения слабой связи посредством внесения совместимых изменений, которые хотя полностью используют описания новой схемы, но не требуют их. Следование указанным правилам расширяемости приводит к созданию документов XML-схема W3C, которые являются более громоздкими и в то же время менее выразительными, чем можно было бы пожелать. Структурные ограничения, которые накладываются в результате задания расширяемости с помощью XML-схемы W3C, являются следствием конструкции XML-схемы W3C, а не врождёнными ограничениями структур, основанных на схеме.

Что касается XML-схемы W3C, то было бы удобно иметь возможность добавлять элементы в произвольных местах, например, перед другими элементами, однако ограничения детерминизма этому препятствуют. Можно было бы воспользоваться менее ограниченной детерминистической моделью, такой как «жадный» алгоритм (greedy algorithm), определённый в спецификации URI [4]. Это разрешило бы располагать необязательные элементы перед групповыми символами и позволило бы устранить потребности в введённом выше типе Extensiontype. Однако, групповые символы по-прежнему недопустимы перед элементами, поскольку вместо этого групповой символ соответствовал бы элементам. Далее, по-прежнему не могут сосуществовать групповые символы и расширения типа. «Приоритетная» модель, в которой элемент мог бы быть сопоставлен с групповым символом или элемент сопоставлялся бы с элементом, если такое возможно, разрешала бы групповые символы до и после объявления элементов. Кроме того, групповой символ, который допускал элементы, которые не были определены — фактически другие пространства имён плюс что-нибудь, не определённое в целевом пространстве имён — ещё одна удобная модель. Эти изменения также разрешили бы более чёткое объединение наследования и групповых символов. Но это также означает, что разработчик схемы должен распределить групповые символы по их типам. Требуется элемент уровня типа в сочетании с вышеупомянутыми изменениями групповых символов. Возможное решение заключается в том, что объявление последовательностей могло бы содержать атрибут, указывающий, что расширения допустимы в любом месте, затем — соответствующие атрибуты, указывающие пространства имён, элементы и правила проверки на допустимость.

Сложность с последним подходом состоит в том, что для конкретной схемы иногда необходимо применять в различных частях системы одну и ту же схему нестрого и нестрого. Давнее правило для Интернет — это принцип устойчивости (Robustness Principle), сформулированный следующим образом в протоколе Internet (Internet Protocol) [3]: «в большинстве случаев реализация должна быть консервативна при отправке сообщений и либеральна при их получении». Применительно к проверке допустимости по схеме отправитель может применять схему строго, а получатель — нестрого. В этом случае степень строгости — это не атрибут схемы, а то, как она используется. Решение, которое, кажется, может решить эти проблемы, — определить форму проверки по схеме, которая разрешит открытую модель содержания, используемую при задании версий схем. Назовём эту модель проверкой допустимости «по отображению» — она работает игнорируя, а не отбрасывая, имена компонентов, которые появляются в сообщении, не являясь явно определёнными в схеме. Автор статьи планирует в будущем рассмотреть эту модель нестрогой проверки допустимости.

Последнее замечание в адрес расширяемости XMLсхемы W3C заключается в том, что по-прежнему остаётся нерешённым вопрос определения схем, которые проверяют допустимость известных расширений, сохраняя при этом расширяемость. Разработчикам схем потребуется не только создавать схему, основанную на расширяемой схеме, но и соединить с другими известными схемами с отдельными групповыми символами, сохраняя при этом расширяемость групповых символов. Автор столкнулся с такой сложностью при описании блоков SOAP header. Вопрос компоновки схем из множества схем хотя и не прост, но требует скорейшего разрешения.

Закончив с рассмотрениеv расширяемости групповых символов, отметим, что использование расширения типов во «Всемирной паутине» могло бы быть более удобным, если бы в реальном документе был выражен базовый тип, когда получатель не понимает тип расширения, например, в выражении xsi:basetype="". Тогда получатель мог бы нейтрализовать неисправность, воспользовавшись базовым типом, если он не понял расширения этого базового типа.

Ещё одна область архитектурного улучшения — обеспечить в XML, или даже XML-схеме W3C, модель mustUnderstand. В настоящий момент каждый словарь, который предоставляет модель mustUnderstand, изобретает заново «колесо mustUnderstand». XML мог бы предоставлять атрибут xml:mustUnderstand и модель, которую мог бы использовать каждый язык. Хотя в феврале 2000г. Тим Бернерс-Ли в своей проектной записке о обязательных расширениях [8] писал о необходимости включения этой модели в XML, она не была добавлена ни в XML 1.0, ни в XML 1.1.

Наконец, сохраняется неоднозначность при испытании реализаций на соответствие XML-схемам W3C. Набор тестов по XML-схемам W3C [16] не охватывает более общие случаи, которые не были рассмотрены в данной статье. Например, тесты включают особый стиль, для которого xs:any находится внутри сложного типа. Однако, они не рассматривают некоторые недетерминистические случаи, обычно возникающие при комбинировании вариаций minOccurs/maxOccurs с ##any или комбинировании наследования с ##any. Следовательно, некоторые реализации не являются корректно оттестированными в случае отсутствия детерминизма, что может привести к появлению неработоспособных документов.

Ещё одна сложность связана с поддержкой в реализациях этих функциональных возможностей и комбинаций. Данные примеры были апробированы в различных парсерах и инструментальных инструментах, предназначенных для работы со схемой, как, например, XML Beans, SQC и JAX-RPC. Несмотря на то, что хотя невозможно выяснить, все ли реализации поддерживают эти правила, то, что было протестировано, похоже обеспечивает хорошую поддержку. Автору статьи, разумеется, будет небезынтересно узнать о инструментальных средствах, которые не обеспечивают поддержку этих правил.

Заключение

Проблема управления версиями и расширяемости оказалась настолько важной для архитектуры Web, что Группа технического проектирования W3C (Technical Architecture Group, сокр. TAG) опубликовала свои заключение по этому вопросу [20] и включила соответствующие материалы в документ «Архитектура Web» (Web Architecture) [21]. Данную статью можно считать отправным моментом при изучении материалов TAG, в документах TAG область рассмотрения шире, а изложение материала носит более последовательный характер. Читатели могут обриться к этим документам за текущей трактовкой вопросов расширяемости и управления версиями.

В этой статье описан ряд правил использования XML, XML-схем W3C и пространства имён XML в конструкциях и расширениях языка. Основная задача этого набора правил — разрешить разработчикам схем вносить в свои языки изменения, поддерживающие обратную и прямую совместимость, чтобы реализовать слабую связь между системами.

В определённой степени описанный подход является комбинацией моделей ##any и ##other с хорошо известными правилами построения схем, которые решают задачу совместимой расширяемости и управления версиями с проверкой допустимости с помощью XML-схемы W3C. Владелец имени пространств имён может вносить в элемент расширяемости изменения, поддерживающие обратную и прямую совместимость, сохраняя возможность проверять допустимость всех компонентов, а другие разработчики схем могут добавлять изменения в расположении группового символа ##other.

Ресурсы

  1. Бесплатный он-лайн словарь по вычислительной технике (Free Online Dictionary of Computing)

  2. Гибкий профиль обработки XML-документов (Flexible XML Processing Profile)

  3. Запрос на комментарии комитета по инженерным вопросам Internet 791 (IETF RFC 791)

  4. Запрос на комментарии комитета по инженерным вопросам Internet 2396 (IETF RFC 2396)

  5. Запрос на комментарии комитета по инженерным вопросам Internet 2518 (IETF RFC 2518)

  6. Запрос на комментарии комитета по инженерным вопросам Internet 2616 (IETF RFC 2616)

  7. SOAP 1.1

  8. WSDL 1.1

  9. Протокол WS-Callback

  10. Спецификация WS-Policy Framework

  11. Примеры успешного использования схем на сайте Xfront (Xfront's Schema Best Practices)

  12. Примечания консорциума W3C «Архитектура Web: расширяемые языки» (W3C Note, Web Architecture: Extensible Languages)

  13. Спецификация консорциума W3C «XML 1.0» (W3C XML 1.0)

  14. Спецификация консорциума W3C «Пространства имён XML» (W3C XML Namespaces)

  15. Спецификация консорциума W3C «XML-схема, Часть 1» (W3C XML Schema Part 1)

  16. Набор тестов Рабочей группы XML Schema консорциума W3C для конструкции Any (W3C XML Schema Working Group's Test collection for Any)

  17. Статья Деара Обасаньо (Dare Obasanjo), опубликованная на ресурсе XML.com, «Принципы проектирования XML-схем» (W3C XML Schema design Patterns)

  18. Работы Тима Бернерса-Ли (Tim Berners-Lee) о развитии, расширяемости и mustUnderstand:

  19. http://lists.w3.org/Archives/Public/w3c-dist-auth/1997AprJun/0190.html

  20. Заключение Группы технического проектирования W3C о расширяемости и управлению версиями (W3C TAG Finding on extensibility and versioning)

  21. Раздел документа Группы технического проектирования W3C «Архитектура Web» о расширяемости и управлении версиями (W3C TAG Web Architecture document section on extensibility and versioning)

Благодарности

Автор выражает благодарность многочисленным рецензентам этой статьи, способствовавшим её написанию, а именно: Дэвиду Бо (David Bau), Уильяму Коксу (William Cox), Эдду Дамбиллу (Edd Dumbill), Крису Фэррис (Chris Ferris), Ярону Голенду (Yaron Goland), Халу Локхарту (Hal Lockhart), Марку Ноттингему (Mark Nottingham), Джеффри Шлиммеру (Jeffrey Schlimmer), Клиффу Шмидту (Cliff Schmidt) и Норману Уолшу (Norman Walsh). В этой статье используются, с разрешения авторов, примеры и часть текста из протокола WS-Callback [9].



XML.com Copyright © 1998-2007 O'Reilly Media, Inc.
Перевод: Intersoft Lab Copyright © 2000-2007 Intersoft Lab