« Поставить закладку » « Сделать стартовой »

« Форумы » « Блоги » « Статьи » « Новости » « Файлы » « Realcoding IRC » « Site map » « Поиск »


Главная Главная
Анонсы Анонсы
Форумы Форумы
Каталог Каталог
Поиск Поиск
Опросы Опросы
Книжный магазин Книжный магазин
Реклама на сайте
Публикации Публикации
Партнеры Партнеры
Карта Карта сайта
Рассылки Рассылки
RSS экспорт
Настройки Настройки
О нас пишут О нас пишут
Контакты Контакты
Гостевая книга Гостевая книга



ПнВтСрЧтПтСбВс
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
    Популярное
DNS в Windows 2003

Функция AccessResource

Динамические массивы в Delphi

Репликация MySQL

Глава 20. Администрирование баз данных.

Прямой доступ к базе данных 1С

Создание собственных средств анализа данных

Что такое PHP-Nuke или Web-портал за 15 минут

Сохранение рисунков

Карандаш и кисть




    Архив файлов



    Сообщества

    Документация

    Кто на сайте
Вы не зарегистрированы.
Имя:

Пароль:

Запомнить

Регистрация позволит Вам пользоваться дополнительными сервисами.
Сейчас на сайте:
Гостей: 185
Пользователей: 0

Статьи:: .NET Framework :: Учебник по ASP.NET :: Глава 5 XML



отправить ссылку другу версия для печати  Обсудить на форуме

Глава 5 XML



История создания
Корни XML
Структура XML-документов
Инструкции XML-процессора
Объявление типа документа
Элементы XML-документа
Атрибуты элементов

Сущности

Комментарии и условные обозначения
Тело XML-документа
XLink. Умные гиперссылки
Создание гиперссылок в XML
Ссылки бывают разные
Локальный ресурс
Внешние ресурсы
Правила прохождения ссылок
Идентифицирующие элементы ссылок
Атрибут типа элемента
Атрибут целеуказания
Семантические атрибуты
Поведенческие атрибуты
Атрибуты прохождения ссылки
XPointer
Основные правила
Абсолютные указатели
Относительные указатели

Абсолютная адресация
Относительная адресация
Адресация интервалов
Адресация строчных субресурсов
Адресация элементов

История создания

Основой WWW является HTML (HyperText Markup Language). Этот язык представляет собой набор тегов, которые позволяют создавать разметку документа, т. е. помимо указания содержимого документа, мы можем при помощи тегов HTML управлять отображением этого документа. Технология проста. Браузер получает HTML-документ и анализирует его. Как только в коде документа встречается какой-либо тег, он распознается, и фрагмент документа, к которому относился тег, оформляется соответствующим образом.

На данный момент доступна уже четвертая версия стандарта языка HTML. Первоначального набора тегов не хватало для нормальной работы. Поэтому компании Microsoft и Netscape, владельцы двух наиболее популярных браузеров дополняли наборы тегов, распознаваемых их браузерами. В силу конкуренции этих двух платформ, указанные дополнения, естественно, не совпадали. Поэтому разработчики либо не использовали дополнительных возможностей, либо отказывались адекватно отображать свой документ в любом браузере. Создавался документ, предназначенный для просмотра в конкретном браузере, а часть посетителей сайта, использующих иной браузер, не могли увидеть данный HTML-документ. Проблемой HTML стала его врожденная ограниченность. Даже самый большой список тегов не в состоянии полностью удовлетворить запросы создателей документов просто в силу того, что этот список ограничен.

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

Исходя из этого, стало ясно, какими свойствами должен обладать преемник HTML. Требовалось, чтобы новый язык был расширяемым, чтобы он не был зависим от конкретного набора тегов. Требовалась возможность расширять язык автоматически, исходя из нужд пользователя. Также было необходимо создавать файлы, которые могли бы не только отображаться, но и обрабатываться сторонними приложениями. Другими словами, структура документов должна была напрямую привязываться к ним. Каждый документ должен содержать как информацию, так и ее структуру.

Исходя из этих и многих других соображений Консорциум World Wide Web (W3C) в 1998 году приступил к разработке спецификаций нового языка, который должен был прийти на смену HTML. Его назвали XML (extensible Markup Language). В этой книге мы рассмотрим эту спецификацию версии 2.0, воспользовавшись документацией самого W3C.

Корни XML

Прежде всего, давайте разберемся, откуда появился XML. Очень давно (по меркам компьютерной индустрии, естественно), в 1986 году организацией ISO (International Organization for Standardization) язык SGML (Standard Generalized Markup Language) был принят в качестве официального стандарта. А использоваться он начал еще раньше. SGML применяется в качестве стандарта до сих пор. Этот язык описывает практически все возможности разметки информации. Язык SGML позволяет разработчику создавать свои конструкции разметки. Потрясающая гибкость и объем, охватывающий практически все случаи, возникающие при работе, казалось бы, делали этот язык идеальным кандидатом для принятия его в качестве основного языка Web, но существовали и другие обстоятельства, которые помешали ему занять это место.

Любые документы из Web прежде всего просматриваются при помощи специализированных программ — браузеров. Браузеры анализируют код полученного документа, и на основе инструкций разметки, называемых также тегами , отображают полученный документ в окне просмотра соответствующим образом. Но спецификация SGML занимает более 500 страниц. Сколько же труда потребовалось бы, чтобы заставить браузеры правильно отображать документы, написанные на SGML. Требовалось что-то более компактное. Поэтому и был создан язык HTML, являющийся очень ограниченным и нерасширяемым подмножеством SGML. Так как набор тегов HTML был невелик, браузеры писать было достаточно легко.

Но потом это достоинство HTML превратилось в его недостаток. Посетителям и владельцам сайтов хотелось получать от HTML все больше и больше. Компании — участники "браузерных войн" добавляли все новые теги во множество распознаваемых своими браузерами инструкций. Основная проблема была в том, что эти добавленные теги у различных компаний тоже были разными. Возникли проблемы с совместимостью. Принятие стандарта HTML версии 4.0 не решило проблемы. Так как HTML представляет собой ограниченный и нерасширяемый набор тегов, то рано или поздно любая версия стандарта окажется недостаточной.

На смену пришел стандарт (а точнее, рекомендация к стандарту) XML (extensible Markup Language). Это расширяемый язык разметки. Набор тегов XML много меньше по объему, чем у HTML, но в данном случае это неважно. Изменилась сама парадигма создания документов. Теперь теги XML используются в качестве строительных блоков конструктора Lego. Мы теперь можем при помощи тегов XML создавать свой язык для каждого типа документов или даже для каждого документа отдельно.

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

XML, как и его предшественник HTML, является подмножеством XGML. Но XML является достаточно компактным языком. Поэтому реализация браузеров для XML-документов не будет являться излишне сложной задачей.

Структура XML-документов

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

Описание структуры документа называют DTD-блоком (Document Type Definition). В нем мы указываем древовидную структуру элементов документа. Наиболее близкой аналогией для этих элементов могут служить объекты. Как и объекты, наши элементы разметки могут иметь свойства, которые в данном случае называются атрибутами.

Как и в любой объектной иерархии, в XML-документе существует некий корневой элемент, от которого наследуются все остальные элементы.

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

Инструкции XML-процессора

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

<?xml version="l.0"?>

Как видно из примера, исполняемые инструкции ограничиваются угловыми скобками с вопросительными знаками. Ключевым словом является конструкция xmi. Следом за ней указываются параметры инструкции и соответствующие им значения. Иногда эти стартовые строки инструкций называют прологом XML-документа.

Приведенный пример предназначен для указания браузеру, что данный документ написан на XML. Параметр version с приведенным значением указывает на то, что будет использоваться первая версия стандарта XML. А другой версии у нас пока и нет.

В этих инструкциях мы можем не только указывать номер версии стандарта. Для XML-документов заготовлено несколько видов кодировок, состоящих из символов набора Unicode. Большинство кодировок предложено международной организацией по стандартизации (ISO).

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

<?xml encoding="UTF-8"?>

В качестве значения параметра используется текстовая строка "utf-s". Кодировка UTF-8 является одной из наиболее часто используемых кодировок.

Следующие параметры инструкций XML-процессора напрямую связаны с обработкой блоков определения типа документа. Забегая немного вперед, необходимо сказать, что подобные блоки могут внедряться в сам XML-документ или находиться отдельно от того документа, к которому они относятся. Для того чтобы XML-процессор смог правильно их обработать, применяется параметр standalone. При помощи этого параметра можно указать, где именно находится блок определения типа документа (DTD-блок) для данного XML-документа. В следующем примере мы используем объявление XML-документа, в котором указывается, что DTD-блок для него сделан в виде отдельного файла.

<?xml standalone='no'?>

У параметра standalone есть два предопределенных значения: yes и по. Значение по, как мы видели, извещает XML-процессор, что для данного документа DTD-блок выделен в отдельный файл. Значение yes указывает на то, что DTD-блок внедрен в сам XML-файл.

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

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

[23] XMLDecl ::= '<?xml' Versionlnfo EncodingDecl? SDDecl? S? '?>'

[24] Versionlnfo ::= S 'version' Eq (' VersionNum ' I " VersionNum ")

[25] Eq ::= S? '='S?

[26] VersionNum ::= ([a-zA-ZO-9_.:] I '-')+

На первый взгляд смотрится это все достаточно устрашающе. Все спецификации XML выглядят подобным образом. Это запись правил XML в форме Бэкуса-Наура EBNF (Extended Backus-Naur Form). Разберемся с правилами чтения деклараций в форме EBNF. В левой части каждой декларации указывается имя конструкции, затем следует оператор эквивалентности (;:=), а в правой части следует расшифровка имени, которая содержит его формат и правила оформления. Перед каждой спецификацией в квадратных скобках указывается номер строки.

Итак, из приведенного фрагмента мы видим, что определение исполняемой инструкции находится в 23-й строке спецификации языка XML. При чтении спецификаций необходимо помнить несколько правил записи определений в форме EBNF.

Если в определении записано несколько терминов, разделенных вертикальной чертой (|), то необходимо выбрать только один из них. Подобным образом определяется перечислимое множество компонентов.

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

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

Знак звездочки (*) устанавливается после некоего символьного выражения, если необходимо, чтобы это выражение в строке могло встречаться несколько раз или не встречаться там вообще. Другими словами, символьное выражение, после которого установлен модификатор звездочки, может находиться в результирующей строке ноль или более раз.

Знак плюса (+) применяется в качестве модификатора символьного выражения подобно знаку звездочки. Но есть некоторое отличие. Символьные выражения, после которых установлен этот модификатор, могут встречаться в результирующей строке один или более раз.

Вопросительный знак (?) используется для указания, что тот или иной элемент могут не находиться в результирующей строке, т. е. при помощи этого модификатора указываются опциональные элементы.

Если в выражении не могут встречаться некоторые символы, то вставляется последовательность [ ^ , после которой указываются исключаемые символы. Например, правило [ ^ &] исключает символ амперсанта.

Если внутри какого-либо литерала необходимо вставить пробел, то этот пробел обозначается при помощи символа s.

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

Зная эти правила, рассмотрим наши декларации. Начнем, естественно, с декларации [23]. В ней объявляется элемент XML Dec1 , который является объявлением XML-документа. После оператора эквивалентности находится литерал '<?xm 1 '. Это означает, что строка объявления XML-документа должна начаться с открывающей угловой скобки, вопросительного знака и последовательности символов xm 1 . Впрочем, этот факт мы знали и до разбора синтаксиса декларации. После этой последовательности символов находится элемент versioninfo, указывающий номер версии применяемого стандарта XML. Помимо этого в объявлении могут находиться элементы EncodingDeci и SDDeci. После них может находиться или не находиться пробел, и завершается конструкция последовательностью символов '?>'.

В приведенном нами фрагменте спецификации XML не приведено определение конструкции SDDeci. Приведем его сейчас.

[32] SDDeci ::= S 'standalone' Eq ((..... ('yes' | 'no') ..... I

("" ('yes' | 'no') ""))

Как видно из этой декларации, значения параметра standalone могут заключаться как в двойные, так и в одиночные кавычки.

Объявление типа документа

Сразу после исполняющей инструкции, указывающей на то, что данный документ создан с применением языка XML, в документе помещается объявление типа документа, называемое также DTD (Document Type Definition). DTD-блок является основой структуризации содержимого XML-файла. В нем находятся правила, по которым происходит разметка содержимого документа. В этом блоке определяются элементы документа, атрибуты для этих элементов, сущности, комментарии. Другими словами, DTD-блок не менее важен для XML-документа, чем его значимое содержимое. Рассмотрим пример объявления типа документа.

<!DOCTYPE body [

<! ELEMENT body (# PCDATA) >

<! ENTITY name "Igor">

В первой строке примера начинается объявление типа документа. Как видно, используется ключевое слово doctype, помещаемое после открывающей угловой скобки и восклицательного знака. Необходимо отметить, что все конструкции XML помещаются в угловые скобки. Но перед большинством из ключевых слов ставится восклицательный знак. А перед исполняемыми инструкциями XML-процессора, как мы помним, ставится вопросительный знак.

После ключевого слова doctype пишется наименование типа. Это, по сути, имя корневого элемента объектной иерархии данного документа. Здесь необходимо сделать некоторое отступление и рассказать немного об элементах XML-документа, которые более полно мы будем рассматривать в следующей части. Но в XML все настолько переплетено и хорошо увязано, что есть только один путь абсолютно последовательного и непротиворечивого изложения правил оформления XML-документов. Это официальная спецификация, части которой мы приводим в тексте этой книги. Так как читать ее трудно, придется немного переплетать изложение различных структурных единиц, принося последовательность изложения в жертву его доступности.

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

Таким образом, в качестве наименования типа XML-документа мы используем имя самого старшего элемента, который включает в себя все остальные документы. В нашем примере это элемент с именем body.

После указания этого имени в квадратных скобках описывается структура всего документа. А после закрывающей квадратной скобки следует закрывающая угловая скобка. Получается, что все определение типа документа находится в рамках одного тега doctype. Все это легко увидеть в коде рассмотренного нами примера.

DTD-блоки могут находиться как внутри XML-документа, так и вне его. Для нескольких XML-документов можно создать один файл с описанием DTD и использовать его для каждого из этих XML-документов. Для подключения внешнего DTD-блока можно использовать конструкцию, подобную этой:

<!DOCTYPE main PUBLIC "-//New Boundaries//Sweet Immersing// EN" "http://www.newboundaries.com/sweet/dtd/main.dtd">

Разберем этот пример. Мы объявляем тип документа main, спецификация которого находится в отдельном DTD-файле. В данном случае объявлено, что это DTD не принято международной организацией по стандартизации (ISO) в качестве стандарта, оно принадлежит компании New Boundaries, создано для проекта Sweet Immersing, ориентировано на англоязычные документы, и файл со спецификацией находится по адресу http://www.newboundaries.com/sweet/dtd/main.dtd.

Ключевое слово public применяется для так называемых "публичных" DTD. Для них помимо URL указывают еще и наименование. Делается это для того, чтобы XML-браузер мог отыскать эти DTD на других серверах, которые, может быть, будут ближе. Конечно, в критериях Интернета понятие "ближе" относится к географии весьма опосредованно, но выбирается всегда тот DTD-файл, который будет быстрее всего загружен на локальную систему удаленного пользователя. Публичные DTD отличаются от обычных обособленных DTD-файлов тем, что могут находиться на нескольких различных серверах.

Еще одна особенность публичных DTD состоит в том, что их рассматривает международная организация по стандартизации (ISO). В том случае, если этот DTD-блок принят в качестве стандарта, перед именем файла (а не перед его URL) ставится префикс iso. Если в качестве стандарта этот DTD не принят, но, тем не менее, рассматривается группой стандартизации, в качестве префикса используется знак плюса (+). Если же он не принят группой стандартизации, используется префикс в виде минуса (-), как мы это видели в нашем примере.

Если же DTD-блок вообще не отправлялся в ISO, то он объявляется "приватным". В таком случае вместо ключевого слова public используется ключевое слово system. При этом применяется конструкция следующего типа:

<!DOCTYPE main SYSTEM "http://www.newboundaries.com/sweet/main.dtd">

Теперь, когда мы знаем, как использовать внешние файлы, содержащие DTD-блоки, следует научиться создавать эти файлы. Любой DTD-файл подчиняется спецификациям XML, т. е. по сути, он является обычным XML-документом, но без значимого содержимого. Поэтому первой строкой снова будет исполняемая инструкция XML-процессора. Но теперь совсем необязательно указывать номер версии стандарта XML. Обычно во внешних DTD-файлах указывают используемую кодировку. После этого определяются все структурные элементы. Так как ссылка на DTD-файл уже встраивается в соответствующий XML-документ, нет нужды в DTD-файле использовать объявление типа документа с ключевым словом doctype.

Мы уже рассматривали параметр standalone для исполняемой инструкции, которая объявляет использование XML. В том случае, если используется внешний DTD-файл, необходимо использовать значение по.

В зависимости от того, как используется DTD-блок, какие правила оформления DTD применяются в XML-документах, эти документы могут называться " хорошо оформленными" (well-formed) и " правильными" (valid). Кстати, некоторые правила спецификации XML являются обязательными для оформления документа, если мы хотим, чтобы этот документ являлся хорошо оформленным или правильным. Для таких правил в спецификации указываются индексы wfc (Well-Formedness Constraint) и vc (Validity Constraint), соответственно. Но чтобы избавить себя от штудирования неудобочитаемой спецификации, рассмотрим эти правила сами.

Итак, для того чтобы документ считался хорошо оформленным, необходимо выполнение нескольких правил.

  • У документа должен быть один элемент верхнего уровня, и содержимое документа должно полностью располагаться между тегами, соответствующими этому элементу-прародителю.
  • В одном теге не могут использоваться несколько раз одни и те же атрибуты элемента, соответствующего этому тегу.
  • Все сущности должны объявляться до их использования.
  • Все теги должны быть правильно вложены друг в друга, согласно иерархии элементов, и у каждого тега должен быть его закрывающий двойник.

По сути дела, все XML-документы, которые будут использоваться в публичных целях, просматриваться в различных браузерах и обрабатываться различными приложениями, должны быть, как минимум, хорошо оформленными. Обязательное использование вышеперечисленных правил обусловлено тем, что при несоблюдении какого-либо из них, обычный XML-процессор выдаст сообщение о фатальной ошибке, после чего приложение, в котором действует XML-процессор, будет остановлено. Более того, кое-где встречается информация о том, что отдельные приложения и браузеры "зависают" при попытке просмотра документов с ошибками.

Следует обратить внимание на то, что в перечне правил для хорошо оформленных документов нет ни слова о DTD-блоках. Связано это с тем, что по спецификации XML DTD-блоки не являются обязательными для использования в XML-документах. Поэтому следующий XML-документ считается правильным, так как не нарушено ни одно из правил.

<?xml version="1.0" standalone="yes"?> <body>well-formed document </body>

Еще раз напоминаю, что XML-процессоры чувствительны к регистру символов.

Правильным считается XML-документ, который удовлетворяет требованиям, предъявляемым к хорошо оформленным документам, и при этом имеет соответствующий DTD-блок и подчиняется всем правилам, описанным в нем.

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

<?xml version="1.0" standalone="yes"?>

<!DOCTYPE body [<!ELEMENT body (#PCDATA)>

]>

<body>valid document </body>

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

[28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternallD)? S?

('['(markupdecl | PEReference | S)* ']' S?)? '>' [VC: Root Element Type ]

[29] markupdecl ::= elementdecl I AttlistDecl I EntityDecl

I NotationDecl | PI | Comment [ VC: Proper Declaration/PE Nesting ]

[ WFC: PEs in Internal Subset ]

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

Элементы XML-документа

Мы уже говорили в предыдущих частях об элементах. Элементы являются основными структурными единицами XML-документов. Мы объявляем все элементы документа в DTD-блоке, а потом при разметке значимого содержимого документа мы используем теги, наименования которых совпадают с наименованиями элементов.

Объявление элемента в самом упрощенном виде мы уже наблюдали в одном примере. Приведем его еще раз.

<!DOCTYPE body [

<!ELEMENT body (IPCDATA)>

Здесь мы объявляем тип документа body, в котором объявляется одноименный элемент. Как видно, объявление элемента производится при помощи ключевого слова element, после которого указывается наименование элемента и его тип. Все эти значимые и обязательные части разделяются пробелами. В данном случае мы объявили элемент с символьным содержимым, применив для этого стандартную конструкцию (#pcdata) .

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

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

<!ELEMENT firm (name+, address, phone*, fax*, email, info)>

<!ELEMENT name (IPCDATA)>

<!ELEMENT address (#PCDATA)>

<!ELEMENT phone (#PCDATA)>

<!ELEMENT fax (#PCDATA)>

<!ELEMENT email (#PCDATA)>

<!ELEMENT info (#PCDATA)>

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

Знак плюса (+) применяется для тех элементов, чье вхождение в родительский элемент является обязательным. Данные элементы могут встречаться в рамках родительского элемента один или более раз. Но хотя бы один раз они должны быть использованы обязательно.

Знак звездочки (*) указывает на то, что данный элемент может встречаться в описании родительского элемента любое количество раз. Впрочем, может там вообще не встречаться.

Вопросительный знак (?) используется для тех элементов, которые могут появляться в описании родительского элемента только один раз, или вообще не появляться.

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

Группировка элементов, как мы знаем, осуществляется при помощи круглых скобок. Применяя запятую, мы фактически устанавливаем порядок следования элементов. Таким образом, в значимом содержимом XML-документа все субэлементы должны следовать именно в том порядке, в котором они записаны в DTD-блоке.

В том случае, если нам необходимо использовать один из некоторого множества субэлементов, это множество дополнительно заключается в круглые скобки, и все наименования субэлементов разделяются вертикальной чертой (|). Например, если бы мы хотели, чтобы в нашем примере для элемента firm можно было бы использовать либо номер факса, либо номер телефона, можно применить следующую декларацию:

<!ELEMENT firm (name+, address, (phone | fax), email, info)>

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

Это, впрочем, не означает, что в атомарных элементах будут находиться единичные и неделимые фрагменты информации. Каждый элемент может обладать атрибутами, которые в свою очередь и будут содержать подобные информационные атомы. Хорошей естественной аналогией для атрибутов являются свойства объектов. Но в этой части мы рассматриваем только элементы. Атрибуты мы будем рассматривать в следующей части.

Итак, нас интересует, как задавать тип для атомарных элементов. Всего есть три варианта.

Если мы собираемся сохранять в элементе какие-либо данные так называемого смешанного типа (mixed content), мы должны указать в круглых скобках тип #pcdata. По сути, под эвфемизмом "смешанный тип" подразумевается использование любых символьных данных.

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

Для обозначения типа пустых элементов (заглушки) используется ключевое слово EMPTY.

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

<!ELEMENT Ь (#PCDATA)> <!ELEMENT br EMPTY>

<!ELEMENT container ANY>

<!ELEMENT p (#PCDATA|a|ul1ЫiI em)*>

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

И в заключение обзора элементов мы должны привести фрагмент спецификации, который описывает объявление элементов.

[45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>' Unique Element Type Declaration ]

contentspec ::= 'EMPTY1 I 'ANY1 | Mixed | children children ::= (choice | seq)

('?' | '*' | '+')? cp :: = (Name | choice | seq) ('?' | '*' | '+')?

[ VC: [46] [47] [48]

[49] choice ::= '(' S? cp ( S? [ VC: Proper Group/PE Nesting ]

[50] seq ::=

S? cp ( S?

[ VC: Proper Group/PE Nesting ]

Атрибуты элементов

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

Список атрибутов задается при помощи ключевого слова attlist. Рассмотрим маленький пример.

<!ELEMENT text (#PCDATA)> <!ATTLIST text

create_date CDATA #REQUIRED

lastjnodified CDATA #IMPLIED

author CDATA #REQUIRED

editor CDATA "Kondukova E.V.">

В этом примере мы объявили элемент text, в котором содержится четыре атрибута. Как видно, после ключевого слова attlist указывается наименование элемента, к которому присоединяются атрибуты, определяемые в данном теге ниже. После наименования элемента записывается список атрибутов. Для каждого атрибута указываются наименование, тип содержимого атрибута и модификатор атрибута.

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

После имени атрибута указывается его тип. Всего может быть три типа. В нашем примере мы использовали атрибуты символьного типа. Для обозначения этого типа применяется ключевое слово с data. В этих атрибутах могут храниться только данные в виде строк. В приведенном выше примере объявлены атрибуты именно такого типа.

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

<!ATTLIST my_element

type (a|b|c) "c">

В этом примере объявляется атрибут type, который может принимать только значения а, b и с, причем по умолчанию используется значение с.

Применяется также и третий тип атрибутов. Подобные атрибуты называются маркерами. Это специализированные атрибуты, значения которых несут заранее предопределенный тип информации об элементе. При использовании атрибутов-маркеров в качестве типа атрибута мы записываем одно из семи ключевых слов, которые идентифицируют вид маркера. Так, например, даже в последней версии стандарта HTML в каждом теге присутствует параметр id, при помощи которого задают идентификатор блока, обрабатываемого данным тегом. В XML этот параметр задан изначально и является атрибутом-маркером. Приведем пример задания подобного атрибута.

<!ATTLIST my_element id ID #REQUIRED>

В этом примере видно, как мы задаем для элемента my_eiement параметр id, для которого указываем тип id.

Как мы уже говорили, есть семь предопределенных типов элементов-маркеров. Рассмотрим их все.

Атрибут типа id предназначен для указания уникального идентификатора данного элемента. Значение этого атрибута должно полностью удовлетворять соглашению об именах в XML. Естественно, идентификаторы всех экземпляров элементов в содержимом XML-документа должны быть разными, иначе нарушается условие уникальности. Если же это условие нарушается, то XML-процессор укажет на ошибку в документе.

Атрибут idref содержит идентификатор другого элемента, с которым данный элемент связан по смыслу. Подобный атрибут предназначен для реализации двунаправленных ссылок, одной из наиболее широко разрекламированных возможностей, вошедших в стандарт XML версии 1.0. Естественно, элемент, идентификатор которого указан в данном атрибуте, должен присутствовать в XML-документе, иначе XML-генератор объявит о недействительности данного документа.

Если данный элемент связан смысловыми взаимоотношениями с несколькими другими документами, то мы можем указать все их идентификаторы сразу в одном атрибуте. Для этого используется атрибут типа idrefs. В его значении все идентификаторы связанных элементов записываются, разделенные пробелами.

Атрибут entity указывает на внешнюю сущность, связанную с данным элементом. В качестве значения этого атрибута указывается имя сущности. Более подробно механизм сущностей мы рассмотрим в следующей части.

Атрибут entities весьма похож на предыдущий. Разница лишь в том, что в его значении мы можем записать сразу несколько имен внешних сущностей.

Атрибут nmtoken содержит любую последовательность символов имени данного элемента.

Идею этого атрибута расширяет атрибут с именем nmtokens, который в своем значении может содержать сразу несколько подстрок имени данного элемента.

Мы рассмотрели типы атрибутов, которые записываются в их объявлениях сразу после наименования атрибута. Но у каждого атрибута есть еще и некая характеристика. Мы можем задать атрибут, который будет обязателен для применения в каждом экземпляре элемента, задать значение по умолчанию для каждого атрибута, и так далее. Есть три стандартных модификатора для атрибутов.

Модификатор #implied указывает на то, что для данного атрибута значение может быть не определено, т. е. этот атрибут не является обязательным для применения.

Модификатор #required наоборот, применяется для указания обязательных атрибутов. А именно, если у данного атрибута некоего элемента есть этот модификатор, то во всех экземплярах элемента в значимом содержимом XML-документа должно быть обязательно присвоено значение этому атрибуту.

Модификатор #fixed применяется в тех случаях, когда заданное для атрибута значение по умолчанию является фиксированным, т. е. не поддается изменению. Проще говоря, единожды объявленное значение атрибута в тексте XML-документа изменить не удастся. Понятно, что этот модификатор не применяется для атрибутов перечислимого типа.

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

<!ELEMENT text (#PCDATA)> <!ATTLIST text

create_date CDATA #REQUIRED

last_modified CDATA #IMPLIED

author CDATA «REQUIRED

editor CDATA "Kondukova E.V.">

Здесь видно, что атрибуты create_date и author являются обязательными, а атрибут iast_modif led может и не использоваться в элементах text. А для атрибута editor предусмотрено значение по умолчанию Kondukova e.v., которое ограничивается двойными кавычками, как строковая переменная. В этом примере значение по умолчанию не комбинируется с модификатором. Пример такого сочетания выглядит следующим образом:

<!ATTLIST hyperlink

xlink:type CDATA #FIXED "simple">

В этом примере мы объявляем элемент hyperlink с атрибутом xiink:type, для которого установлено фиксированное значение simple. Следовательно, каждый раз, когда в тексте XML-документа будет использоваться элемент hyperlink, его атрибут xiink:type будет всегда иметь значение simple, и изменить это значение в тексте XML-документа для какого-либо экземпляра элемента будет нельзя.

Атрибуты перечислимого типа мы можем комбинировать со списком условных обозначений (notation). Механизм подобных списков мы будем рассматривать в одной из следующих частей. А сейчас нам необходимо просто привести пример подобного комбинирования. После наименования атрибута мы указываем в качестве его типа ключевое слово notation. Затем, как обычно в скобках, указываем сами условные обозначения, входящие в данный список. А после перечисления вписываем значение, используемое по умолчанию. Все это можно увидеть в следующем примере:

<!ATTLIST new_element

attr NOTATION (first I second]third) "third">

Естественно, в DTD-блоке должно присутствовать определение подобного списка, в котором определяются все элементы списка.

Итак, мы рассмотрели все правила создания атрибутов. Теперь приведем фрагмент спецификации, который описывает создание атрибута.

[52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>' [53] AttDef ::= S Name S AttType

S DefaultDecl [54] AttType ::= StringType I TokenizedType I EnumeratedType [55] StringType ::= 'CDATA' [56] TokenizedType ::= 'ID' [ VC: ID ] [ VC: One ID per Element Type ]

С VC: ID Attribute Default ] 'IDREF' [ VC: IDREF ] 'IDREFS' [ VC: IDREF ] 'ENTITY' [ VC: Entity Name ] 'ENTITIES' [ VC: Entity Name ] 'NMTOKEN' [ VC: Name Token ]

 'NMTOKENS' [ VC: Name Token ] EnumeratedType ::= NotationType NotationType ::= 'NOTATION' S '(

{58] li

(59] Enumeration numeration ]

VC: Notation Attributes ]

= ' (' S? Nmtoken (S?

Enumeration

S? Name (S? 'I' S? Name)'

S? Nmtoken)* S? ')'

S?

VC:

DefaultDecl ::= 'IREQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)

[ VC: Required Attribute ] [ VC: Attribute Default Legal ]

 [ WFC: No < in Attribute Values ] [ VC: Fixed Attribute Default ]

Сущности

Сущности являются одним из ключевых элементов XML. Под ними обычно донимают единый и неделимый блок информации, который не анализируется XML-генератором. Сущности могут представлять собой файлы с бидарной информацией, такой как рисунки, аудио- и видеофайлы, документы, обрабатываемые специализированными приложениями, и многое другое. I Также в качестве сущностей используются часто применяемые блоки информации. Достаточно их объявить в качестве сущности в DTD-блоке потом во всех XML-документах, подключенных к этому DTD-блоку, можно применять обозначение этой сущности. Таким образом, если необходимо изменить этот элемент, мы можем изменить его в одном месте, в объявлении сущности, и изменения во всех связанных с этим DTD-блоком XML-документах будут сделаны автоматически. Также сущности могут применяться и в самом DTD-блоке для оформления часто встречающихся последовательностей атрибутов или элементов, т. е. выполняют обычную функцию текстовой подстановки. При помощи все тех же сущностей мы можем вставлять в текст XML-документа неотображаемые символы. По сути, любая сущность является контейнером для каких-либо данных, помещаемых в XML-документ. Все эти ипостаси мы тщательно рассмотрим, и приведем соответствующие примеры.

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

Сущности по своему типу делятся на текстовые, бинарные и параметрические. По своему месту определения, декларирования мы можем сущности делить на внешние и внутренние.

Любая сущность объявляется в DTD-блоке при помощи ключевого слова entity. После него, отделенное пробелом, следует наименование сущности, ее псевдоним. А затем, уже в самом конце декларации мы вписываем содержимое сущности, заключенное в двойные кавычки. В качестве примера наиболее простой текстовой сущности приведем следующую конструкцию:

<!ENTITY cp "copyright disclaimer">

Теперь, если в тексте XML-документа мы вставим наименование этой сущности, обрамленное знаками амперсанта и точки с запятой, то оно при отображении документа браузером, будет заменено на соответствующее словосочетание. То есть в тексте для вызова сущности мы должны использовать конструкцию &ср;.

Также существуют и предопределенные текстовые сущности. В значимом содержимом XML-документа мы можем применять только символы из набора ASCII. Все остальные символы будут вставляться в текст только при помощи сущностей. По существу, все кодировки представляют собой набор сущностей. Наиболее распространенные кодировки приведены в приложении.

В ASCII-наборе есть несколько символов, которые не могут самостоятельно вставляться в текст XML-документа. Это служебные символы, применяемые в разметке кода XML-документа, такие как знаки "больше" и "меньше", знак амперсанта (&), а также одинарные и двойные кавычки. Для вставки этих символов в текст значимого содержимого XML-документа используются сущности Sgt;, Sit;, Samp;, &apos; И &quot; соответственно.

Бинарные сущности позволяют вставлять в текст XML-документа любые внешние файлы, от графических изображений, до файлов Microsoft Office, не забывая, естественно, мультимедиа-файлы. Вообще, любые файлы можно присоединить к XML-документу, необходимо лишь указать какие приложения должны вызываться для обработки того или иного файла. Приведем пример сущности, которая подключает графический GIF-файл:

<!ENTITY picture SYSTEM "/images/picl.gif" NDATA gif>

Все двоичные сущности будут внешними, так как они встраивают внешние по отношению к XML-документу файлы. Поэтому после объявления имени, так называемого псевдонима сущности, следует ключевое слово system, следом за которым указывается URL подключаемого файла. Все это достаточно прозрачно, так как не противоречит ничему, что мы узнали о разметке XML ранее. Но есть одно достаточно тонкое место. XML-процессор "не знает" о том, какой именно тип файла мы используем. Он не обязан автоматически распознавать тип файла по расширению. Поэтому для каждого типа файлов, используемого в оформлении, необходимо указать программу, применяемую для обработки данного типа файла. Для этого используется механизм условных обозначений (notation), который мы рассмотрим в следующей части детально. Здесь мы приведем маленький пример. Если мы в объявлении сущности picture использовали тип gif, указав его после ключевого слова ndata, то в DTD-блоке должно присутствовать следующее объявление условного обозначения:

ONOTATION gif SYSTEM "http://www.mysite.ru/progs/gifview.exe">

В этом объявлении мы указываем, что для обработки файлов типа gif необходимо вызвать приложение, URL которого указан после ключевого слова ; SYSTEM в двойных скобках.

В объявлении бинарной сущности необходимо внимательно следить за типом файла, указываемом после ключевого слова ndata. Каким бы ни было расширение подключаемого файла, XML-процессор не будет принимать его во внимание. Тип устанавливается по соответствующему обозначению.

Однако есть одна возможность создавать и использовать бинарные внешние сущности без указания типа присоединяемого файла. Это имеет место, если I вставляются сторонние XML-файлы. При помощи этого средства мы можем t собирать объемный XML-документ из других документов. Другими словами, s если у нас уже есть три XML-файла, содержимое которых необходимо объединить в одно целое, следует объявить их как внешние бинарные сущности, и вызвать в основном документе при помощи их псевдонимов. Приведем соответствующий пример.

<!xml version="1.0">

<!DOCTYPE body [

<!ENTITY docl SYSTEM "http://www.parts.ru/partl.xml">

<!ENTITY doc2 SYSTEM "http://www.parts.ru/part2.xml">

<!ENTITY doc3 SYSTEM "http://www.parts.ru/part3.xml">

]>

А в теле документа следует использовать следующую конструкцию:

<body>

Sdocl;

Sdoc2;

Sdoc3;

</body>

При этом мы можем использовать в объявлении внешней бинарной сущности не только ключевое слово system, но и public. Но в этом случае мы должны использовать только те файлы, которые рассматривались международной организацией по стандартизации. Но с другой стороны, так ли уж необходимо Вам стандартизировать свои данные?

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

Эти сущности объявляются и вызываются внутри DTD-блока. Естественно, параметрическую сущность сначала необходимо объявить, а уже потом — использовать.

Есть и еще одно отличие от обычных сущностей. Для вызова параметрических сущностей, перед их псевдонимом мы должны поставить не знак амперсанта, а знак процента. Этот же знак процента ставится и при объявлении параметрической сущности.

Приведем маленький пример. Нам необходимо объявить два разных элемента, причем у каждого из них частично будут совпадать наборы атрибутов. Эту-то совпадающую часть мы и объявим как параметрическую сущность, а затем используем ее в декларировании самих элементов.

<!ENTITY % common_atts "

#IMPLIED #IMPLIED #REQUIRED">

CDATA CDATA ID

last_modified

description

id

<!ELEMENT el_first (#PCDATA}> <!ELEMENT el_second (#PCDATA)> <!ATTLIST el_first

special_attribut CDATA #IMPLIED

%common_atts;> <!ATTLIST el_second

sex (male I female)

%common_atts;>

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

Теперь детально рассмотрим механизмы объявления внутренних и внешних сущностей. Объявление внутренних сущностей не представляет особых проблем. Вся информация, входящая во внутреннюю сущность, находится внутри одного DTD. Для декларирования внутренней сущности необходимо после псевдонима сущности указать само содержимое сущности. В случае использования внешних сущностей после псевдонима необходимо указать тип ссылки на содержимое сущности. Как и все внешние ресурсы, содержимое сущности может быть как обычным, так и стандартизованным. Если используется обычный внешний ресурс, то в объявлении после псевдонима мы указываем ключевое слово system, а затем URL ресурса, являющегося содержимым ссылки. Если же содержимое сущности по какому-либо недоразумению было отослано в ISO и прошло там рассмотрение, то после псевдонима мы указываем ключевое слово public, затем официальное наименование ресурса, а уже после него — URL содержимого.

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

S1ENTITY ср "All rights are protected">

tlENTITY pic SYSTEM "http://www.graphics.com//images/c3.gif" NDATA gif>

:[ENTITY firm PUBLIC " + //New Boundaries//Sweet Iramersing//EN" P'http://www.bound.com/dtd/f.xml">

Теперь, когда мы рассмотрели правила объявления и применения сущностей, узнали, что это такое и для чего они нужны, разобрали несколько примеров, необходимо привести фрагмент официальной спецификации CML, в котором описываются сущности. Что ж, вот он.

[ 67] Reference ::= EntityRef | CharRef

[ 68] EntityRef ::= '&' Name ';' [ WFC: Entity Declared ]

[ VC: Entity Declared ]

[ WFC: Parsed Entity ]

[ WFC: No Recursion ]

[69] PEReference ::= '%' Name ';' [ VC: Entity Declared ]

[ WFC: No Recursion ]

[ WFC: In DTD ]

[70] EntityDecl ::= GEDecl I PEDecl

[71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'

[72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'

[73] EntityDef ::= EntityValue | (ExternallD NDataDecl?)

[74] PEDef ::= EntityValue | ExternallD

[75] ExternallD ::= 'SYSTEM' S SystemLiteral

I 'PUBLIC' S PubidLiteral S SystemLiteral

[76] NDataDecl ::= S 'NDATA' S Name [ VC: Notation Declared ]

Комментарии и условные обозначения

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

Итак, условные обозначения являются специальными элементами DTD, которые позволяют ассоциировать тип файла, включаемого в значимое содержимое XML-файла, и приложение, которое будет обрабатывать эти файлы. XML-браузеры не занимаются отображением иных файлов, таких как графика, аудио- или видеофайлы, самостоятельно, в отличие от известных нам HTML-браузеров. Для этих целей используются их "родные" приложения.

Условное обозначение задается при помощи ключевого слова notation, после которого указывается наименование типа файла (тип файла совсем не обязательно должен совпадать с его расширением, хотя это очень удобно) без ограничивающих кавычек, а затем — URL обрабатывающего приложения. Так как все приложения являются внешними ресурсами по отношению к данному XML-файлу, то, естественно, необходимо использовать ключевые слова system или public.

Приведем пример связки внешней бинарной сущности и соответствующего ей условного обозначения. Внешняя сущность будет ссылаться на графический gif-файл, а условное обозначение задаст URL приложения, которое будет отображать этот файл.

<!ENTITY pict SYSTEM "http://www.graphix.net//images/c2.gif" NDATA gif> <!NOTATION gif SYSTEM "file://c:/Program Files/acdsystem/acdsee.exe"> При этом нужно помнить, что если в объявлении внешней бинарной сущности после ключевого слова ndata будет указан неверный тип файла, например "avi", то будет вызван обработчик не для gif-файлов, а именно для avi-ресурсов, несмотря на расширение самого файла.

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

[82] NotationDecl : := '<!NOTATION' S Name S (ExtemallD | PublicID) S? '>'

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

В XML комментарии обозначаются очень просто. Они ограничиваются сочетаниями символов <!-- и -->. В качестве примера можно привести следующую конструкцию:

<!— Это комментарий —>

Официальная спецификация XML описывает комментарии следующим образом:

F15J Comment ::= '<!--' «Char- '-') ( ('-' (Char- '-')))* '-->'

На этом мы заканчиваем рассмотрение элементов DTD и можем переходить к оформлению самих XML-документов.

Тело XML-документа

Теперь, после того, как мы полностью обозначили структуру документа, можно приступать к созданию самого документа. Главное в нем, все-таки, Вне разметка, а его наполнение. Как и в HTML, разметка значимого содержимого производится при помощи тегов. Наименования тегов совпадают с наименованиями элементов, объявленных в DTD-блоке. При этом должна полностью соблюдаться последовательность вложенности тегов. Иначе говоря, все содержимое документа заключено между тегами, которые определенны основным элементом — типом документа. Если какие-либо элементы проходят в качестве составных частей в другие элементы, то и соответствующие теги должны точно так же вкладываться друг в друга с соблюдением «иерархии. Все это можно проиллюстрировать одним примером цельного XML-документа.

 <?xml version="1.0"?>

<!DOCTYPE body [

<!ELEMENT book (chapter) *>

<!ELEMENT chapter (#PCDATA)>

<!ENTITY name "Igor">

]>

<body>

 <book>

 <chapter>Hello, world.

<chapter>Hello, world.

</book>

</body>

В этом примере мы объявляем DTD-блок, в котором объявлен тип документа body, затем объявляем элемент book, составной частью которого является атомарный элемент chapter. Этот атомарный элемент может несколько раз встречаться в одном экземпляре элемента book.

После DTD-блока мы начинаем работать с самим документом. Так как основной элемент объявлен типом документа, мы, соответственно, сначала открываем тег <body>, а в самом конце документа закрываем его. В этот блок мы вкладываем тег <book>, а в него уже вкладываем два набора тегов ; <chapter>.

В этом же примере видно, как используется обычная внутренняя текстовая сущность. В DTD-блоке мы объявляем ее с псевдонимом name, а затем используем в текстовой строке, относящейся к одному экземпляру элемента chapter.

Естественно, та информация, которую мы ограничиваем теми или иными тегами, должна полностью соответствовать по типу тому элементу, к которому она относится. Есть только один тип элементов, для которого приведенный пример не будет работать. В том случае, если мы объявили пустой элемент, т. е. при указании его типа в декларации этого элемента мы использовали ключевое слово empty, то и тег, соответствующий этому элементу, должен быть пустым. Но экземпляры пустых элементов, это не просто открывающий и закрывающий теги, без какой-либо информации между ними. Для обозначения пустых элементов мы должны использовать соответствующие пустые теги. Их применение показано в следующем примере.

<!ELEMENT nothing EMPTY> <nothing/>

В примере видно, что пустые элементы отражаются в XML-документе при помощи одного тега, в конце которого стоит наклонная черта.

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

Как вообще мы можем использовать атрибуты элементов в XML-документе? Рассмотрим пример.

<!ELEMENT computer EMPTY> <!ATTLIST computer

stone CDATA iIMPLIED

memory CDATA #IMPLIED

sound (yes|no) #IMPLIED>

<computer stone="Coppermine" memory="256" sound="yes"/>

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

Атрибуты в тегах содержимого XML-документа используются для задания дополнительных данных, относящихся к существующему экземпляру элемента. Как видно из примера, данные для атрибутов помещаются в тело тега в виде имя=значение, причем значение заключается в двойные кавычки.

Теперь, после того, как мы знаем, как создавать значимое содержимое XML-документа, мы можем рассмотреть законченный документ в качестве примера.

Листинг 5.1

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE body [

<!ELEMENT firm (name+, address+, management, phone*, e-mail, description)>

<!ELEMENT name (#PCDATA)>

<!ELEMENT address (#PCDATA)>

<!ELEMENT management (#PCDATA)>

<!ELEMENT phone (#PCDATA)>

<!ELEMENT e-mail (#PCDATA)>

<!ELEMENT description(#PCDATA)>

<!ELEMENT paragraph (#PCDATA)>

<!ATTLIST address

property (real I official) #REQUIRED>

<!ATTLIST management

owner CDATA #IMPLIED

CEO CDATA #IMPLIED

CFO CDATA #IMPLIED

CIO CDATA #IMPLIED>

<!ENTITY copyright "Businee SuperBase Inc, 2000, All rights reserved"> ]>

<body>

<firm>

<name>IBM</name>

<address property="real">unknown</address>

<management>respectable men</management>

<e-mail>ibm@ibm.com</e-mail>

<description>small hardware company</description>

</firm>

<firm>

<name>Microsoft</name>

<address property="real">Redmond, USA</address>

<management owner="Billy, great and awful">cool</management>

<e-mail>info@microsoft.com</e-mail>

<description>big software company</description>

</firm>

<paragraph>&copyright;</paragraph>

</body>

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

Итак, в этом примере мы объявляем элемент body в качестве типа данного документа, в качестве корневого элемента. В него уже входят обычные элементы paragraph и firm. Элемент paragraph является атомарным, а в элемент firm входят дочерние субэлементы. Так как все субэлементы имеют "говорящие" имена, поэтому в особой расшифровке не нуждаются.

Легко заметить, что для двух субэлементов объявлены наборы атрибутов, которые позволяют детализировать информацию элемента.

Также в DTD-блоке объявлена текстовая сущность с информацией об авторских правах. Так как мы не можем напрямую использовать какие-либо текстовые данные в XML-документе, мы специально создали элемент paragraph, который и будет служить контейнером для всех текстовых данных. В предпоследней строке кода XML-документа видно, как используется предварительно объявленная текстовая сущность.

На самом деле, DTD-блок не является обязательной частью для XML-документов. Если мы удалим из нашего примера весь DTD-блок, он, тем не менее, будет отображаться практически также. Правда, вместе с DTD-блоком мы должны будем удалить из значимого содержимого XML-документа все ссылки на сущности, объявленные в DTD-блоке. Необходимо учитывать, что без DTD-блока XML-документ не будет считаться правильным (valid). А отображаться документ будет точно так же.

А пока мы закончим рассмотрение стандарта XML, и перейдем к технологии XLink, которая разработана для создания гиперссылок нового поколения.

XLink. Умные гиперссылки

Для создания гиперссылок в XML-документах существует свой язык — XLink. Основной идеей XML было радикальное расширение возможностей HTML. He,менее революционный прорыв был сделан и в области гиперссылок. Теперь гиперссылки не являются однонаправленными. При помощи XLink мы можем создавать двунаправленные ссылки (туда — обратно), мультинаправленные ссылки, создавать кольцо ссылок на однородные ресурсы. Мы можем управлять поведением XML-браузера при осуществлении перехода по гиперссылке. При помощи гиперссылок, созданных в XLink, мы в состоянии автоматически устанавливать режим просмотра ресурса, на который эта гиперссылка указывает. Теперь мы способны сделать если не все, то очень многое.

Все гиперссылки в XML-документе являются обычными элементами. Но в них обязаны быть некоторые предустановленные параметры. Все эти детали мы рассмотрим в следующих частях этой главы. Одна из важных частей концепции новых гиперссылок, которые в XML теперь называют "умными ссылками" (smart links), это указание ресурса, на который ссылается ссылка. Мы можем как напрямую указывать целый документ, на который будет указывать гиперссылка, так и указывать относительное положение ресурса. Для этого был создан специализированный язык для целеуказания, который называется XPointer.

Одной из основных проблем Интернета являются "висячие ссылки", которые возникают в том случае, если ресурс, на который они указывают, был удален, изменен или перемещен. В этом случае ссылка ведет в никуда. Возникает стандартная "ошибка 404", которая регистрируется при переходе по оборванной ссылке. Знакомая ситуация, не правда ли?

Так вот, XLink если и не решает эту проблему полностью, то, по крайней мере, снимает некоторые проблемы. Уже за это стоит использовать XML, если всех вышеперечисленных достоинств Вам не хватило.

Создание гиперссылок в XML

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

В XML мы можем создавать как обычные гиперссылки (simple links), знакомые нам еще по HTML, так и расширенные гиперссылки (extended links). А уже из расширенных ссылок мы можем создавать группы расширенных ссылок (extended link groups) и иные виды гиперссылок.

Рассмотрим атрибуты элементов, необходимые для создания различных видов таких ссылок.

У каждого элемента, которому отводится роль ссылки, причем, вне зависимости от типа создаваемой ссылки, должен быть атрибут xlink:href, значение которого содержит точку назначения гиперссылки, и атрибут xlink:type, в котором указывается тип создаваемой гиперссылки. Самый простой вариант объявления обычной гиперссылки выглядит следующим образом:

<!ELEMENT my_link ANY> <!ATTLIST my_link

xlink:type CDATA IFIXED "simple"

xlink:href CDATA #REQUIRED>

Как видно из примера, атрибут xml:type всегда будет иметь модификатор #fixed, так как тип ссылки не меняется. Атрибут xmirhref, естественно, всегда должен присутствовать во всех экземплярах элемента, следовательно, он всегда будет объявляться с модификатором #required.

Теперь, после разбора маленького примера, мы рассмотрим основные варианты создания ссылок.

Ссылки бывают разные

Как мы уже говорили, ссылки в XLink делятся на простые и расширенные. Естественно, это не единственная классификация ссылок, но чаще всего применяется именно такое разделение.

Итак, простые ссылки (simple links) являются прямыми наследниками ссылок из HTML, так хорошо нам знакомых. В силу их простоты, на них не накладывается особых ограничений по внутреннему синтаксису. Нам достаточно указать их тип и ресурс, на который она ссылается.

С расширенными ссылками (extended links) все немного сложнее. В связи с тем, что их функциональность намного выше, чем у простых ссылок, на синтаксис расширенных ссылок накладываются некоторые правила. Итак, прежде всего, необходимо указать тип при помощи атрибута xiinkrtype, использовав для него фиксированное значение extended.

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

<!ELEMENT exlink (source)+> <!ELEMENT cource ANY> <!ATTLIST exlink

xlink:type CDATA #FIXED "extended"> <!ATTLIST source

xlink:type CDATA #FIXED "locator"

xlink:href CDATA #REQUIRED>

<exlink>

<source xlink:href="http://www.sitel.com">First site</source>

<source xlink:href="http://www.site2.com">Second site</source>

<source xlink:href="http://www.site3.com">Third site</source>

</exlink>

В этом примере мы объявляем расширенную ссылку exlink, в которую вхо-дят один или несколько субэлементов source типа locator. Наша расширенная гиперссылка позволяет адресовать сразу три внешних ресурса. Именно для этого и применяются элементы типа locator.

Помимо подобных указателей, в расширенную гиперссылку могут входить элементы типа arc, которые устанавливают правила прохождения гиперссылок, элементы типа title, позволяющие устанавливать отображаемые метки для расширенных гиперссылок, и элементы типа resource, адресующие внутренние ресурсы для нашей гиперссылки. Субэлементы этого типа могут входить поодиночке или группами в каждую расширенную гиперссылку. Рассмотрим пример, включающий в себя все эти типы элементов.

<!ELEMENT courseload ((tooltip I person|course|gpaI go)*)>

<!ATTLIST courseload

xlink:type (extended) #FIXED "extended"

xlink:role CDATA #IMPLIED

xlink:title CDATA #IMPLIED>

<!ELEMENT tooltip ANY> <!ATTLIST tooltip

xlink:type (title)

xml:lang CDATA <!ELEMENT person EMPTY>

<!ATTLIST person

#FIXED "title" IIMPLIED>

xlink:type (locator)

xlink:href CDATA

xlink:role CDATA

xlink:title CDATA

xlink:label NMTOKEN

<!ELEMENT course EMPTY>

<!ATTLIST course

xlink:type (locator)

xlink:href CDATA

xlink:role CDATA "http://www.example.com/linkprops/course"

IFIXED "locator"

tREQUIRED

#IMPLIED

#IMPLIED

|IMPLIED>

#FIXED "locator"

tREQUIRED

#FIXED

xlink:title CDATA xlink:label NMTOKEN

<!ELEMENT gpa ANY>

<!ATTLIST gpa

xlink:type (resource) xlink:role CDATA

#IMPLIED #IMPLIED>

#FIXED "resource"

IFIXED "http://www.example.com/linkprops/gpa"

xlink-.title CDATA # IMPLIED

xlink:label NMTOKEN #LMPLIED>

<!ELEMENT go EMPTY>

<!ATTLIST go

xlink:type (arc) ttFIXED "arc"

xlink: a.rcrole xlink:title xlink.-show

xlink:actuate

CDATA CDATA

(new

I replace

I embed

I other

I none)

(onLoad

IonRequest

I other

I none)

NMTOKEN

NMTOKEN

#IMPLIED #IMPLIED

#IMPLIED

#IMPLIED #IMPLIED #IMPLIED>

xlink:from xlink:to

А использовать это объявление можно при помощи следующего кода:

<courseload xlink:title="Course Load for Pat Jones"> <person

xlink:href="students/patjones62.xml"

xlink:Iabel="student62"

xlink:role="http://www.example.com/linkprops/student"

xlink:title="Pat Jones" />

<person

xlink:href="profs/j aysmith7.xml"

xlink:label="prof7"

xlink:role="http://www.example.com/linkprops/professor"

xlink:title="Dr. Jay Smith" />

<!— more remote resources for professors, TAs, etc. —> <course

xlink:href="courses/cs!01.xml"

xlink:label="CS-101"

xlink:title="Computer Science 101" />

<!— more remote resources for courses, seminars, etc. —>

<gpa xlink:label="PatJonesGPA">3.5</gpa> <go

xlink:from="student62"

xlink:to="PatJonesGPA"

xlink:show="new"

xlink:actuate="onRequest"

xlink:title="Pat Jones's GPA" />

<go

xlink:from="CS-101"

xlink:arcrole="http://www.example.com/linkprops/auditor" xlink:to="student62" xlink:show="replace" xlink:actuate="onRequest"

xlink:title="Pat Jones, auditing the course" />

<go

xlink:from="student62"

xlink:arcrole="http://www.example.com/linkprops/advisor" xlink:to="prof7" xlink:show="replace" xlink:actuate="onRequest" xlink:title="Dr. Jay Smith, advisor" />

</courseload>

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

Мы используем три атрибута для расширенной гиперссылки, такие как xlink:type, xlink:role И xlink:title. Атрибут xlink:type мы уже знаем, а остальные мы будем тщательно рассматривать в следующих частях этой главы. Пока что можно сказать, что атрибут xlink:role позволяет задавать роль ссылки, а атрибут xlink: title — ее заголовок.

Теперь рассмотрим субэлементы, используемые в гиперссылке. Элемент tooltip носит тип title, и у него существует еще один атрибут xmi-. lang, при помощи которого указывается язык элемента.

Следующий субэлемент — person. Он является пустым, как это видно из его объявления. Общий тип этого элемента, входящего в качестве составной части в расширенную гиперссылку, объявлен как locator. Локаторами обычно называют фрагменты расширенных гиперссылок, которые идентифицируют ресурс. На этот ресурс указывает или может указывать расширенная гиперссылка. По сути, локаторы являются адресами ресурсов.

В качестве необязательных атрибутов данного элемента используются xlink:role, xlink:title И xlink:label.

Данный субэлемент в нашем примере используется для указания на ресурс, который содержит информацию о каком-либо человеке, как видно из кода значимого содержимого XML-документа. Если быть более точным, то этим элементом адресуется какой-либо студент или преподаватель, так как наш пример направлен именно на предметную область высшего образования.

Следующий субэлемент, входящий в состав расширенной ссылки, предназначен для указания на ресурс, в котором содержится описание какого-либо обучающего курса. Из этих курсов складывается учебная программа студентов. В субэлементе course, который, как и предыдущий, имеет тип locator, мы помимо обязательного атрибута xiink:href, объявляем набор дополнительных атрибутов. Как и в предыдущем субэлементе, это атрибуты