Определения и
классификация примитивов
Механизм примитивов в XML
является средством повышения производительности,
а также способом встраивать различные типы
данных в ваш XML-документ. В XML-документе вы
можете определить часто используемый блок XML-текста
как примитив, что позволяет вам быстро вставлять
текст в нужное место. Вы можете также определить
как примитив внешний файл, чтобы иметь
возможность включать данные файла в вашем
документе; эти данные могут содержать XML-текст,
другой текст, либо не текстовые данные. Вы
определяете примитив в описании типа документа (DTD)
с использованием синтаксиса, аналогичного тому,
который используется для объявления элемента или
атрибута в валидном XML-документе. О DTD и
объявлениях типа документа, содержащего их,
говорилось в лекции 5.
В
спецификации XML термин примитив (entity) в
широком смысле относится к любому из следующих
типов единиц хранения информации для XML-документов.
- Собственно XML-документ
как целое.
- Внешнее
подмножество DTD (см. раздел "Использование
внешних подмножеств DTD" в лекции 5).
- Внешний файл,
определенный как внешний примитив в DTD и
допускающий использование посредством ссылки.
- Строка в кавычках,
определенная как внутренний примитив в DTD и
допускающая использование посредством ссылки.
Заметим, что
первые три типа единиц хранения информации
являются файлами, а последний – строкой символов,
заключенных в кавычки.
В этой лекции,
термин примитив используется в узком смысле, а
именно, для обозначения внешнего файла или
строки в кавычках, определенных как примитив в
DTD документа и допускающих использование в
документе посредством ссылок на примитивы.
Например, следующее DTD определяет внешний файл
Topics.xml (этот файл содержит список тем в
статье, включенной в документ) как внешний
примитив с именем topics, а также строку в
кавычках ("A Short History of XML") как
внутрений примитив с именем title:
<!DOCTYPE ARTICLE
[
<!ELEMENT ARTICLE (TITLEPAGE, INTRODUCTION, SECTION*)>
<!ELEMENT TITLEPAGE (#PCDATA)>
<!ELEMENT INTRODUCTION (#PCDATA)>
<!ELEMENT SECTION (#PCDATA)>
<!ENTITY topics SYSTEM "Topics.xml">
<!ENTITY title "A short History of XML">
]
>
Впоследствии
вы можете вставить полный список тем в любое
нужное вам место статьи (например, в аннотацию,
введение или заключение), просто включив ссылку
на примитив &topics; – как для следующего
элемента:
<INTRODUCTION>
This article will cover the following topics:
&topics;
</INTRODUCTION>
Вы можете
вставить название статьи в любое место, включив
ссылку на примитив &title; – как для следующего
элемента:
<TITLEPAGE>
Title: &title;
Author: Michael Young
</TITLEPAGE>
Механизм
примитивов наиболее полезен при наличии часто
используемых фрагментов XML-текста. Например,
если название статьи многократно фигурирует по
ее тексту, использование примитива (как в
предыдущем примере) позволит сократить время
набора, добиться однородности и облегчить
внесение изменений в название. Вы можете
изменить текст названия, встречающегося в
различных листах статьи, просто отредактировав
объявление примитива в DTD. Например:
<!ENTITY title "A Long
History of XML">
<! -- модифицированное объявление примитива -->
Если вы
знакомы с программированием, то легко уловите
сходство между механизмом использования
примитивов XML и определением констант в языках
программирования (например, объявления с помощью
инструкции #define в C).
Механизм
примитивов также необходим при включении не XML-данных
в XML-документ (например, графические данные для
изображения).
Типы примитивов
Существует
множество разновидностей примитивов. Материал,
излагаемый в этом разделе, может показаться
довольно абстрактным (прежде, чем вы
познакомитесь с деталями и рассмотрите примеры),
возвращение к этой информации впоследствии
позволит значительно облегчить восприятие
примитивов.
Примитивы
классифицируются по трем признакам:
- общие и
параметрические. Общий примитив включает
содержимое документа – т.е. XML-текст или
другие текстовые или не текстовые данные,
которые вы можете использовать внутри
элемента Документ. Оба примера примитивов,
рассмотренных в предыдущем разделе (title и
topics) относятся к общим примитивам.
Параметрический примитив содержит XML-текст,
который может быть помещен в DTD. В
спецификации XML термин примитив относится к
общим примитивам;
- внутренние и
внешние. Внутренний примитив содержится
внутри строки в кавычках (примитив title в
предыдущем разделе). Внешний примитив
содержится в отдельном файле (примитив
topics в предыдущем разделе);
- разбираемый или не
разбираемый. Разбираемый примитив содержит
XML-текст (символьные данные, разметка или
то и другое). Когда вы вставляете ссылку на
разбираемый примитив в документ, ссылка
замещается содержимым примитива (замещающий
текст), который становится составной частью
документа. Синтаксический анализатор XML
разбирает (сканирует) содержимое примитива
точно так же, как он сканирует
непосредственно введенный в документ текст.
Оба примера примитивов, рассмотренных в
предыдущем разделе (title и topics) являются
разбираемыми примитивами.
Не
разбираемый примитив может содержать любой
тип данных: XML-данные или, что чаще, не
XML-данные. Не XML-данные могут представлять
собой либо текстовые данные (например,
название) или не текстовые данные (например,
графические данные для изображения).
Поскольку не разбираемый примитив обычно не
содержит XML, его содержимое нельзя
непосредственно вставить в документ
посредством ссылки на примитив. Тем не менее,
вы можете связать с именем примитива атрибут
типа ENTITY
или ENTITIES,
чтобы приложение получило доступ к имени
примитива и его описанию, а также могло
работать с его данными.
Поскольку
примитивы классифицируются по этим трем
признакам и в каждой классификации имеются две
категории, теоретически существует восемь
потенциальных типов примитивов, как показано на
диаграмме (см. рис. 6.1).
Однако три
типа примитивов из этих восьми в XML не
поддерживаются (на диаграмме они зачеркнуты).
Следовательно, реально в XML имеется только пять
типов примитивов:
- общие внутренние
разбираемые;
- общие внешние
разбираемые;
- общие внешние не
разбираемые;
- параметрические
внутренние разбираемые;
- параметрические
внешние разбираемые.
О том, как
определять и использовать их, вы и узнаете в
этой лекции.
Рис. 6.1.
Объявление общих
примитивов
Примитив
создается путем объявления его в DTD документа.
Вы объявляете примитив с использованием
разновидности объявления разметки, схожей с той,
которая используется для объявления элементов и
атрибутов. В последующих разделах вы узнаете,
как объявлять каждый из типов общих примитивов.
Объявление общего
внутреннего разбираемого примитива
Объявление
общего внутреннего разбираемого примитива имеет
следующую форму записи:
<!ENTITY ИмяПримитива
ЗначениеПримитива>
Здесь
ИмяПримитива есть
имя примитива. Вы можете выбрать любое имя,
следуя следующим правилам:
- имя должно
начинаться с буквы или с символа
подчеркивания (_), после чего может
следовать одна или несколько букв, цифр,
точек (.), тире (–) или символов
подчеркивания;
- примитив может
иметь такое же имя, что и параметрический
примитив в документе. (Общие примитивы и
параметрические примитивы занимают различные
пространства имен.) Примитив также может
иметь такое же имя, как элемент или атрибут;
- помните, что для
всего текста внутри разметки имеет значение
регистр, в котором набраны символы. Это
относится и к именам примитивов. Так,
примитив с именем Bowser и примитив с именем
bowser будут считаться различными.
ЗначениеПримитива
есть значение примитива. Значение, которое вы
присваиваете общему примитиву, представляет
собой группу символов, заключенных в кавычки,
которая также носит название литерал. Вы можете
присвоить любое значение типа литерал общему
внутреннему примитиву, соблюдая при этом
следующие правила:
- строка должна быть
заключена в одинарные (') или в двойные (")
кавычки;
- строка не может
содержать тот же символ кавычек, который
используется в качестве ограничителей;
- строка не может
содержать символ амперсанда (&), если только
он не используется в качестве первого
символа в указании ссылки на символ или на
общий примитив. Строка также не должна
содержать символ процентов (%). (Чтобы
познакомиться с возможными исключениями,
обратитесь к разделу 4 спецификации XML,
которую вы можете найти по адресу
http://www.w3.org/TR/REC-xml.);
- содержимое строки
должно быть корректным для места, в которое
вы предполагаете вставить примитив. Например,
если вы помещаете примитив внутрь элемента,
он должен содержать один или несколько
компонентов, которые могут быть корректно
вставлены в другие элементы (вложенные
элементы, символьные данные и т.д., как
описано в разделе "Типы содержимого элемента"
в лекции 3). Либо, если вы вставляете
примитив внутрь значения атрибута, он должен
содержать символы, которые являются
допустимыми для значений атрибута (см.
раздел "Правила для корректного задания
значений атрибутов" в лекции 3). Далее в
этой лекции вы узнаете, куда можно помещать
общие внутренние разбираемые примитивы.
Например,
следующее DTD определяет общий внутренний
разбираемый примитив с именем title:
<!DOCTYPE ARTICLE
[
<!ELEMENT ARTICLE (TITLEPAGE, INTRODUCTION, SECTION*)>
<!ELEMENT TITLEPAGE (#PCDATA | SUBTITLE)*>
<!ELEMENT SUBTITLE (#PCDATA)>
<!ELEMENT INTRODUCTION (#PCDATA)>
<!ELEMENT SECTION (#PCDATA)>
<!ENTITY title
"The Story of XML
<SUBTITLE>The Future Language of the
Internet</SUBTITLE>">
]
>
Примитив
title содержит символьные данные плюс элемент (SUBTITLE).
В соответствии с объявлением в DTD это
содержимое может быть корректно вставлено только
в элемент TITLEPAGE,
как показано ниже:
<TITLEPAGE>
Title: &title;
Author: Michael Young
</TITLEPAGE>
XML-процессор
заменит ссылку на примитив (&title;) содержимым
примитива и обработает содержимое, как если бы
вы непосредственно набрали его в документе в
позиции ссылки, подобно следующему:
<TITLEPAGE>
Title: The Story of XML
<SUBTITLE>The Future Language of the Internet</SUBTITLE>
Author: Michael Young
</TITLEPAGE>
Объявление общего
внешнего разбираемого примитива
Объявление
для общего внешнего разбираемого примитива имеет
следующую форму записи:
<!ENTITY ИмяПримитива
SYSTEM СистемЛитерал>
Здесь
ИмяПримитива есть
имя примитива. Вы можете выбрать любое имя,
следуя правилам задания имен для общих
примитивов, приведенным в предыдущем разделе.
СистемЛитерал есть
системный литерал, который описывает
местонахождение файла, содержащего данные
примитива. Системный литерал может быть
ограничен одинарными (') или двойными (")
кавычками и содержать любые символы, кроме
символа кавычек, используемого как ограничители.
Системный
литерал задает унифицированный идентификатор
ресурса (URI) файла, содержащего данные
примитива. На сегодняшний день URI практически
то же самое, что стандартный Internet-адрес,
известный как унифицированный указатель ресурса
(URL). Вы можете использовать либо полный URI,
например:
<!ENTITY abstract
SYSTEM "HYPERLINK 'http://bogus.com/documents/Abstract.xml'
http://bogus.com/documents/Abstract.xml">
либо
частичный URI, который задает местонахождение
относительно местонахождения XML-документа,
содержащего URI, например:
<!ENTITY abstract
SYSTEM ":Abstract.xml">
Относительные URI в XML-документах работают
аналогично относительным URL для HTML-страниц.
Для более подробной информации об URI обратитесь
к разделу "Использование только внешнего
подмножества DTD" в лекции 5.
Файл
внешнего примитива может содержать только те
составляющие, которые могут быть корректно
вставлены в элемент (символьные данные,
вложенные элементы и т.д., как описано в разделе
"Типы содержимого элемента" в лекции 3). Вы
можете вставить общий внешний разбираемый
примитив только внутрь содержимого элемента. (Можно
включить его в значение в объявлении внутреннего
примитива, но затем нужно вставить это
содержимое в элемент.)
Например,
следующее DTD определяет внешний файл Topics.xml
как общий внешний разбираемый примитив:
<!DOCTYPE ARTICLE
[
<!ELEMENT ARTICLE (TITLEPAGE, INTRODUCTION, SECTION*)>
<!ELEMENT TITLEPAGE (#PCDATA)>
<!ELEMENT INTRODUCTION ANY>
<!ELEMENT SECTION (#PCDATA)>
<!ENTITY topics SYSTEM "Topics.xml">
]
>
Вот
содержимое файла Topics.xml:
<HEADING>Topics</HEADING>
The Need for XML
The Official Goals of XML
Standard XML Applications
Real-World Uses for XML
Этот
типичный файл внешнего примитива содержит два
пункта, которые вы можете включить в XML-элемент:
вложенный элемент и блок символьных данных. Его
содержимое может быть корректно вставлено в
элемент INTRODUCTION
(который может иметь любой тип содержимого), как
показано в следующем примере:
<INTRODUCTION>
Here’s what this article covers:
&topics;
</INTRODUCTION>
Объявление общего
внешнего неразбираемого примитива
Объявление
для общего внешнего неразбираемого примитива
имеет следующую форму записи:
<!ENTITY ИмяПримитива
SYSTEM СистемЛитерал NDATA ИмяНотации>
Здесь
ИмяПримитива есть
имя примитива. Вы можете выбрать любое имя,
следуя правилам, приведенным в разделе "Объявление
общего внутреннего разбираемого примитива" ранее
в этой лекции.
СистемЛитерал есть
системный литерал, который описывает
местонахождение файла, содержащего данные
примитива. Он действует точно так же, как
системный литерал для описания местоположения
общего внешнего разбираемого примитива (см.
предыдущий раздел).
Примечание. Ключевое
слово NDATA
указывает, что файл примитива содержит не
разбираемые данные (они не обрабатываются
синтаксическим анализатором).
ИмяНотации есть
имя нотации, объявленной в DTD. Нотация
описывает формат данных, содержащихся в файле
примитива, или указывает на местонахождение
программы, которая может обрабатывать эти данные.
Об объявлении нотации будет говориться в
следующем разделе.
Файл
неразбираемого внешнего примитива может
содержать любой тип текста или не текстовые
данные. Они должны, конечно, соответствовать
описанию формата, определяемого соответствующей
нотацией.
Например,
DTD в следующем XML-документе определяет файл
Faun.gif (который содержит рисунок обложки книги)
как общий внешний не разбираемый примитив с
именем faun. Имя нотации этого примитива – GIF.
Она указывает на местонахождение программы,
которая отображает графические файлы в формате
GIF (ShowGif.exe). DTD также определяет пустой
элемент с именем
COVERIMAGE и атрибут типа
ENTITY для этого
элемента с именем Source:
<?xml version="1.0"?>
<!DOCTYPE BOOK
[
<!ELEMENT BOOK (TITLE, AUTHOR, COVERIMAGE)>
<!ELEMENT TITLE (#PCDATA)>
<!ELEMENT AUTHOR (#PCDATA)>
<!ELEMENT COVERIMAGE EMPTY>
<!ATTLIST COVERIMAGE Source ENTITY #REQUIRED>
<!NOTATION GIF SYSTEM "ShowGif.exe">
<!ENTITY faun SYSTEM "Faun.gif" NDATA GIF>
]
>
<BOOK>
<TITLE>The Marble Faun</TITLE>
<AUTHOR>Nathaniel Hawthorne</AUTHOR>
<COVERIMAGE Source="faun" />
</BOOK>
В элементе
Документ атрибуту Source
элемента COVERIMAGE
присвоено имя внешнего примитива, который
содержит графические данные для отображения
рисунка обложки. Поскольку
Source имеет тип
ENTITY, вы можете
присвоить ему имя общего внешнего неразбираемого
примитива. Фактически единственный способ
использования этого типа примитива состоит в
присвоении его имени атрибуту с типом
ENTITY или
ENTITIES.
Примечание. В отличие
от файла внешнего разбираемого примитива, к
файлу внешнего неразбираемого примитива XML-процессор
прямого доступа не имеет. Процессор просто
делает примитив и его нотацию доступными
приложению, которое может выполнять
необходимые действия с этой информацией. (Например,
оно может запустить программу,
ассоциированную с нотацией, и указать ей
отобразить данные из файла примитива.) В
лекции 9 вы узнаете, как писать сценарии
Web-страниц, которые могут получать доступ к
примитивам и нотациям.
Объявление нотаций
Нотация
описывает определенный формат данных. Это
делается путем указания адреса описания формата,
адреса программы, которая может обрабатывать
данные в этом формате, либо просто описание
формата. Вы можете использовать нотацию, чтобы
описать формат общего внешнего неразбираемого
примитива (см. в предыдущем разделе), либо
можете присвоить нотацию атрибуту, который имеет
нумерованный тип NOTATION
(см. раздел "Задание нумерованных типов" в
лекции 5).
Нотация
имеет следующую форму записи:
<!NOTATION ИмяНотации
SYSTEM СистемЛитерал>
Здесь
ИмяНотации есть
имя нотации. Вы можете выбрать любое имя, при
условии, что оно начинается с буквы или символа
подчеркивания (_), после чего могут идти или не
идти другие буквы, цифры, точки (.), тире (–)
или символы подчеркивания. Лучше выбирать
информативное имя, позволяющее идентифицировать
формат. Например, если вы определяете нотацию,
описывающую точечный формат (bitmap), вам
следует использовать имя BMP.
СистемЛитерал есть
системный литерал, который может быть ограничен
одинарными (') или двойными (") кавычками и
содержать любые символы, за исключением символа
кавычек, используемого в качестве ограничителя.
Вы можете включить в системный литерал любое
описание формата, которое проинформирует
приложение, как отображать или обрабатывать XML-документ.
(Помните, что XML-процессор сам не использует
информацию нотации; он просто передает ее
приложению, в качестве которого может выступать
сценарий на Web-странице.) Например, вы можете
включить в системный литерал одно из следующих
описаний.
- URI программы,
которая может обрабатывать или отображать
формат данных, как в следующих примерах:
<!NOTATION BMP
SYSTEM "Pbrush.exe">
<!NOTATION GIF SYSTEM "HYPERLINK
'http://bogus.com/ShowGif.exe'
http://bogus.com/ShowGif.exe">
- URI документа в
сети, который описывает формат данных,
например:
<!NOTATION
STRANGEFORMAT SYSTEM "http://bogus.com/StrangeFormat.htm">
- Простое описание
формата, например:
<!ENTITY %
ИмяПримитива ЗначениеПримитива>
Дополнительная информация об URI и примеры
приведены в разделе "Использование только
внешнего подмножества DTD" в лекции 5.
Объявление
параметрических примитивов
Форма
объявления разметки параметрического примитива
аналогична форме объявления, используемой для
общих примитивов. В последующих разделах вы
узнаете, как объявлять оба типа параметрических
примитивов.
Объявление
параметрического внутреннего разбираемого
примитива
Объявление
для параметрического внутреннего разбираемого
примитива имеет следующую общую форму записи:
<!ENTITY %
ИмяПримитива ЗначениеПримитива>
Здесь
ИмяПримитива есть
имя примитива. Вы можете выбрать любое имя,
соблюдая следующие правила:
- имя должно
начинаться с буквы или символа подчеркивания
(_), вслед за которым могут идти или не идти
буквы, цифры, точки (,), тире (–) или
символы подчеркивания;
- примитив может
иметь такое же имя, что и общий примитив в
документе. (Параметрические и общие
примитивы занимают различные пространства
имен.) Имя примитива также может совпадать с
именем элемента или атрибута;
- помните, что для
всего текста разметки, в том числе и для
имен примитивов, имеет значение регистр, в
котором набраны символы. Так, примитив под
именем Spot будет отличаться от примитива
под именем spot.
ЗначениеПримитива
есть значение примитива. Значение, присваиваемое
параметрическому примитиву, представляет собой
группу символов, заключенных в кавычки (литерал).
Вы можете присвоить параметрическому примитиву
любое значение типа литерал, при условии
соблюдения следующих правил:
- строка должна быть
ограничена одинарными (') или двойными (")
кавычками;
- строка не может
содержать символов кавычек, которые
используются в качестве ограничителей;
- строка не может
содержать символа процентов (%) и символа
амперсанда (&), если это не начальный символ
в ссылке на символ или общий примитив;
- вы можете
поместить параметрический примитив в DTD
только как объявление разметки, но не внутри
объявления разметки. Следовательно, строка
ЗначениеПримитива должна содержать один или
несколько типов объявлений разметки, которые
разрешено использовать в DTD. Эти типы
объявлений разметки описаны в разделе "Создание
DTD" в лекции 5. В частности,
параметрический примитив может содержать
объявления типа элемента, объявления списка
атрибутов, объявления общих примитивов,
объявления нотаций, инструкции по обработке,
или комментарии. (Объявления параметрических
примитивов и ссылки не допускаются.)
Примечание.
Приведенные здесь правила использования
значений примитивов, которые вы можете без
опасения применять в любых ситуациях,
являются несколько упрощенными в отличие от
правил, содержащихся в спецификации XML.
Спецификация, в определенных обстоятельствах,
разрешает вам включать в значение примитива
дополнительные составляющие, а также
помещать ссылку на примитив внутри разметки
и между объявлениями разметки. Подробности
приведены в разделе 4 спецификации XML,
которую вы можете найти по адресу
http://www.w3.org/TR/REC-xml.
Например,
следующее DTD объявляет параметрический
внутренний разбираемый примитив с именем author,
который содержит три объявления разметки:
комментарий, объявление типа элемента и
объявление списка атрибутов. Содержимое
примитива (т.е. замещающий его текст) помещается
в конец DTD посредством ссылки на
параметрический примитив (%author;);
<!DOCTYPE BOOK
[
<!ENTITY % author
"<!-- информация об авторе -->
<!ELEMENT AUTHOR (#PCDATA)>
<!ATTLIST AUTHOR Nationality CDATA
'American'>"
>
<!ELEMENT BOOK (TITLE, AUTHOR)>
<!ELEMENT TITLE (#PCDATA)>
%author;
]
>
Обратите
внимание, что значение атрибута по умолчанию,
которое содержится в объявлении примитива
('American'), ограничено одинарными кавычками,
чтобы избежать использования такого же символа,
который применяется для ограничения всего
значения примитива. Приведенное выше DTD
эквивалентено следующему:
<!DOCTYPE BOOK
[
<!ELEMENT BOOK (TITLE, AUTHOR)>
<!ELEMENT TITLE (#PCDATA)>
<! -- информация об авторе -->
<!ELEMENT AUTHOR (#PCDATA)>
<!ATTLIST AUTHOR Nationality CDATA 'American'>
]
>
Объявление
параметрического внешнего разбираемого примитива
Объявление
для параметрического внешнего разбираемого
примитива имеет следующую форму записи:
<!ENTITY %
ИмяПримитива SYSTEM СистемЛитерал>
Здесь
ИмяПримитива есть
имя примитива. Вы можете выбрать любое имя,
следуя правилам задания имен для параметрических
примитивов, приведенных в предыдущем разделе.
СистемЛитерал есть
системный литерал, который описывает
местонахождение файла, содержащего данные
примитива. Системный литерал может быть заключен
в одинарные (') или двойные (") кавычки и
содержать любые символы, за исключением символа
кавычек, который используется в качестве
ограничителя.
Системный
литерал задает URI файла, содержащего данные
параметрического примитива. В настоящее время
URI практически аналогичен стандартному
унифицированному указателю ресурса Internet
(URL). Вы можете использовать как полностью
заданный URI, например:
<!ENTITY %
declarations
SYSTEM "HYPERLINK 'http://bogus.com/documents/Declarations.dtd'
http://bogus.com/documents/Declarations.dtd">
Либо вы
можете использовать частичный URI, задающий
местонахождение относительно местонахождения
XML-документа, содержащего URI, например:
<!ENTITY %
declarations SYSTEM "Declarations.dtd">
Относительные URI в XML-документах работают
подобно относительным URL для HTML-страниц. Для
более подробной информации об URI обратитесь к
разделу "Использование только внешнего
подмножества DTD" в лекции 5.
Файл
параметрического внешнего примитива должен
содержать полные объявления разметки всех типов,
допустимых в DTD. В частности, он может
содержать объявления типа элемента, объявления
списка атрибутов, объявления примитивов,
объявления нотаций, инструкции по обработке, или
комментарии. (Эти типы объявлений разметки
описаны в разделе "Создание DTD" в лекции 5.) Вы
также можете включать ссылки на параметрические
примитивы и разделы INCLUDE и IGNORE. (См.
раздел "Условное игнорирование разделов внешнего
подмножества DTD" в лекции 5.)
Вы можете
использовать параметрические внешние разбираемые
примитивы для хранения группы взаимосвязанных
объявлений. Допустим, вы занимаетесь продажей
книг, CD-ROM, плакатов и другой продукции. Вы
можете поместить объявления для каждого вида
продукции в отдельный файл. Это позволит вам
объединять эти группы объявлений различными
способами. Например, вы хотели бы создать XML-документ,
который описывает только имеющиеся у вас в
наличии книги и CD-ROM. Для этого вы можете
поместить объявления для книг и CD-ROM в DTD
документа с помощью параметрических внешних
разбираемых примитивов, как показано в следующем
примере XML-документа:
<?xml version="1.0"?>
<!DOCTYPE INVENTORY
[
<!ELEMENT INVENTORY (BOOK | CD)*>
<!ENTITY % book_decls SYSTEM "Book.dtd">
<!ENTITY % cd_decls SYSTEM "CD.dtd">
%book_decls;
%cd_decls;
]
>
<INVENTORY>
<BOOK>
<BOOKTITLE>The Marble Faun</BOOKTITLE>
<AUTHOR>Nathaniel Hawthorne</AUTHOR>
<PAGES>473</PAGES>
</BOOK>
<CD>
<CDTITLE>Concerti Grossi Opus 3</CDTITLE>
<COMPOSER>Handel</COMPOSER>
<LENGTH>72 minutes</LENGTH>
</CD>
<BOOK>
<BOOKTITLE>Leaves of Grass</BOOKTITLE>
<AUTHOR>Walt Whitman</AUTHOR>
<PAGES>462</PAGES>
</BOOK>
<!-- дополнительные виды продукции… -->
</INVENTORY>
Вот
содержимое файла примитива Book.dtd:
<!ELEMENT BOOK (BOOKTITLE,
AUTHOR, PAGES)>
<!ELEMENT BOOKTITLE (#PCDATA)>
<!ELEMENT AUTHOR (#PCDATA)>
<!ELEMENT PAGES (#PCDATA)>
А вот
содержимое файла примитива CD.dtd:
<!ELEMENT CD (CDTITLE,
COMPOSER, LENGTH)>
<!ELEMENT CDTITLE (#PCDATA)>
<!ELEMENT COMPOSER (#PCDATA)>
<!ELEMENT LENGTH (#PCDATA)>
Заметим,
что параметрический внешний разбираемый примитив
работает во многом аналогично внешнему
подмножеству DTD. Параметрические внешние
примитивы, однако, обеспечивают большую гибкость
– они разрешают вам включать несколько файлов
внешних объявлений, причем в любом порядке. (Напомним,
что внешнее подмножество DTD всегда
обрабатывается после того, как полностью будет
обработано подмножество внутреннего DTD.)
Вставка ссылок на
примитив
Вставка
содержимого (замещающий текст) примитива в
документ осуществляется с помощью ссылок на
примитив. Вы уже познакомились с несколькими
примерами ссылок на примитив. Общий вид ссылки
на общий примитив следующий:
&ИмяПримитива;
а на
параметрический примитив:
%ИмяПримитива;
где
ИмяПримитива есть
имя, присваиваемое примитиву в объявлении.
Исключением является общий внешний не
разбираемый примитив, который вы не можете
вставить с использованием ссылки. Единственный
способ использования этого типа примитива
заключается в присвоении его имени атрибуту,
имеющему тип ENTITY
или ENTITIES. (См.
раздел "Задание маркерного типа" в лекции 5.)
Объявление
примитива должно предшествовать любой ссылке на
этот примитив.
Для каждого
типа примитива в представленной ниже таблице
приведена форма записи ссылки на примитив и
перечень возможных мест помещения ссылки на
примитив. В таблице также приведены ссылки на
разделы в этой лекции, в которых вы можете найти
примеры. О ссылках на символы речь пойдет далее
в этой лекции, но данный вид ссылок также
включен в таблицу для полноты картины.
Тип примитива |
Форма записи
ссылки на примитив, где
ИмяПримитива
есть имя примитива |
Место, в
которое вы можете поместить ссылку
на примитив (пример) |
Общий внутренний разбираемый |
&ИмяПримитива; |
В
содержимое элемента (см. "Объявление
общего внутреннего разбираемого
примитива")
В значение атрибута (как
значение по умолчанию в объявлении
атрибута, либо в начальном теге
элемента) (см. "Ссылка на примитив
Пример 1")
|
|
|
В
значение в объявлении внутреннего
примитива (см. "Ссылка на примитив
Пример 2") |
Общий внешний разбираемый |
&ИмяПримитива; |
В
содержимое элемента (см. "Объявление
общего внешнего разбираемого
примитива") |
Общий внешний не разбираемый |
АтрПрим=’ИмяПримитива’
где
АтрПрим
есть атрибут типа
ENTITY
или ENTITIES
|
В
значение в объявлении внутреннего
примитива (см. "Ссылка на примитив
Пример 2")
Вы не можете
поместить ссылку на этот тип
примитива, но можете присвоить имя
примитива атрибуту, имеющему тип
ENTITY
или ENTITIES
(см. "Объявление общего внешнего
неразбираемого примитива")
|
Параметрический внутренний
разбираемый |
%ИмяПримитива |
В
DTD в место помещения объявлений
разметки, но не внутри объявлений
разметки (исключения приведены в
разделе 4 спецификации XML, доступ
по адресу http://www.w3.org/TR/REC-xml)
(см. "Объявление параметрического
внутреннего разбираемого примитива") |
Параметрический внешний разбираемый
|
%ИмяПримитива |
В
DTD в место помещения объявлений
разметки, но не внутри объявлений
разметки (исключения приведены в
разделе 4 спецификации XML, доступ
по адресу http://www.w3.org/TR/REC-xml)
(см. "Объявление параметрического
внешнего разбираемого примитива") |
Ссылка на символ |
	 или &#xh; где 9 – десятичный
числовой код символа, а h –
шестнадцатеричный числовой код
символа |
В
содержимое элемента (см. "Вставка
ссылок на символы") |
|
|
В
значение атрибута (в качестве
значения по умолчанию в объявление
списка атрибутов, или в начальный
тег элемента) (см. "Вставка ссылок
на символы") |
|
|
В
значение в объявлении внутреннего
примитива (см. "Вставка ссылок на
символы") |
Ссылка на примитив
Пример 1
В следующем
XML-документе объявлены два общих внутренних
разбираемых примитива, am и en. Документ
использует ссылку на am для присвоения значения
по умолчанию атрибуту
Nationality и ссылку на en для присвоения
значения атрибуту
Nationality элемента
AUTHOR.
Преимущество использования примитива здесь
заключается в том, что вы можете изменить
значение по всему документу (в предположении,
что в нем имеется много элементов) простым
редактированием определения примитива (например,
изменив значение en с "English" на "British").
<!DOCTYPE INVENTORY
[
<!ENTITY am "American">
<!ENTITY en "English">
<!ELEMENT INVENTORY (BOOK*)>
<!ELEMENT BOOK (TITLE, AUTHOR)>
<!ELEMENT TITLE (#PCDATA)>
<!ELEMENT AUTHOR (#PCDATA)>
<!ATTLIST AUTHOR Nationality CDATA "&am;">
]
>
<INVENTORY>
<BOOK>
<TITLE>David Copperfield</TITLE>
<AUTHOR Nationality="&en;">Charles
Dickens</AUTHOR>
</BOOK>
<!-- другие элементы… -->
</INVENTORY>
Ссылка на примитив
Пример 2
Следующее
DTD определяет общий внутренний разбираемый
примитив (int_entity) и общий внешний
разбираемый примитив (ext_entity). Затем он
определяет другой общий внутренний разбираемый
примитив, combo_entity,
и помещает оба предыдущих примитива в значение
примитива combo_entity.
<!DOCTYPE INVENTORY
[
<!ENTITY int_entity "internal entity value">
<!ENTITY ext_entity SYSTEM "Entity.xml">
<!ENTITY combo_entity
"значение, состоящее из &ext_entity; плюс &int_entity;">
<!-- другие объявления разметки… -->
]
>
Вставка ссылок на
символы
Вы можете
воспользоваться ссылкой на символ, чтобы
вставить символ, которого нет на вашей
клавиатуре (например, a), либо вставить символ,
который не допускает его вставку в данном
контексте как литерал (например, символы < или &
в составе символьных данных элемента). Вам не
нужно делать какие-либо определения перед
использованием ссылки на символ – вы можете
просто поместить ее в нужном месте.
Ссылка на
символ имеет две различные формы. Первая форма:
	
где 9 – это
одна или несколько десятичных цифр (от 0 до 9),
представляющих числовой код символа в наборе
символов ISO/IEC 10646.
Вторая
форма ссылки на символ:
&#xh;
где h – это
одна или несколько шестнадцатеричных цифр (от 0
до F), также представляющих числовой код символа
в наборе ISO/IEC 10646.
Например,
обе ссылки A и A означают вставку
прописной буквы A. (Числовой код для A равен
десятичному числу 65 и шестнадцатеричному числу
41.)
Международная таблица символов ISO/IEC 10646
используется для числового представления
символов практически любых языков. (ISO –
International Organization for Standardization,
IEC – International Electrotechnical
Commission.) Коды первых 128 символов совпадают
с кодами хорошо известного набора ASCII,
используемого в большинстве компьютеров. На
представленном ниже рисунке содержатся первые
256 символов в наборе ISO/IEC 10646. Для каждого
элемента на рисунке 6.2 первое число (1:, 2:,
3:, и т.д.) есть десятичный код символа, а после
двоеточия следует символ – если он есть – в том
виде, в котором он отображается Microsoft
Internet Explorer 5.
Рис. 6.2.
Например,
из рисунка вы можете определить, что десятичный
код символа для a равен 228. Чтобы вставить этот
символ в ваш документ, достаточно ввести ссылку:
ä
Примечание. Список
мест, в которые вы можете поместить ссылку
на символ в вашем документе, приведен в
таблице в разделе "Вставка ссылок на
примитивы" ранее в этой лекции. Там же
приведены и примеры.
Для
следующего элемента символ левой угловой скобки
(<) вставляется в символьные данные элемента с
помощью ссылки на символ < (60 есть
десятичный код для <). Напомним, что
непосредственная вставка символа < в символьные
данные не допускается.
<TITLE><The Legend
of Sleepy Hollow></TITLE>
Для
следующего элемента ссылка на символ ä
используется для вставки символа a (вы не можете
ввести его с клавиатуры) в значение атрибута:
<RESIDENT Address="Seilerstätte
30, Wien">Mike Young</RESIDENT>
В следующем
объявлении общего внутреннего разбираемого
примитива в DTD ссылка на символ %
используется для вставки символа процентов (%)
(37 есть десятичный код для %), который не может
быть непосредственно введен как литерал в
значение внутреннего примитива:
<!ENTITY heading1
"% Complete">
Использование
предварительно определенных примитивов
В XML-документе
вы можете использовать ссылку на заранее
определенный примитив, чтобы вставить следующие
пять стандартных символов в места, куда вставка
символов как литералов не допускается:
Ссылка на
предопределенный примитив |
Вставляемый
символ |
Эквивалентная
ссылка на символ |
& |
& |
& |
< |
< |
< |
> |
> |
> |
&apos |
' |
' |
" |
" |
" |
Вставка
этих ссылок на предопределенный примитив
эквивалентна вставке соответствующей ссылки на
символ. Ссылки на предопределенные примитивы
легче запомнить, а документ при этом легче
воспринимается.
Эти
предопределенные примитивы похожи на другие
общие внутренние разбираемые примитивы, за
исключением того, что ссылки на них вы можете
использовать без определения примитивов – и вы
можете вставлять их в те же места, что и
примитивы данного типа, а именно:
- в содержимое
элемента;
- в значение
атрибута (как значение по умолчанию в
объявлении атрибута или в начальном теге
элемента);
- в значение в
объявлении внутреннего примитива.
В следующих
трех примерах ссылки на предопределенные
примитивы используются для вставки символов,
которые не допускается вставлять как литералы.
В первом
примере ссылка < используется для вставки в
содержимое элемента левой угловой скобки (<):
<TITLE><The Legend
of Sleepy Hollow></TITLE>
Во втором
примере ссылка & используется для вставки
амперсанда (&) в значение атрибута:
<PRODUCT Company="Ongaro
& Sons">3/4" T fitting</PRODUCT>
В третьем
примере ссылка " используется для вставки
двойных кавычек (") в значение примитива (их
нельзя вставить как литерал, поскольку такие же
кавычки используются как ограничители строки):
<!ENTITY heading
"Christopher "Kit" Carson">
Объявление документа
автономным (standalone)
Вы можете
включить объявление автономности (standalone)
документа в XML-объявление (см. лекцию 3,).
Объявление standalone сообщает процессору,
требуются ли внешние объявления для обработки
документа.
Если XML-документ
имеет внешние объявления разметки (либо во
внешнем подмножестве DTD, либо в параметрическом
внешнем разбираемом примитиве), но ни одно из
этих объявлений не оказывает влияния на
содержимое документа, передаваемого XML-процессором
приложению, вы можете установить для standalone
значение 'yes' или "yes", как в следующем XML-объявлении:
<?xml version="1.0"
standalone="yes"?>
Установка
предотвращает ненужную обработку внешних файлов.
Установка для standalone значения 'no' или "no",
либо пропуск объявления standalone сообщает
процессору, что он должен обработать все внешние
объявления разметки, поскольку одно или
несколько из них оказывают влияние на содержимое
документа.
Если вы
хотите познакомиться с типами внешней разметки,
которые влияют на содержимое документа (и
следовательно, не допускают установку для
standalone значения "yes"), обратитесь к разделу
9 спецификации XML, которую можете найти по
адресу http://www.w3.org/TR/REC-xml.
Добавление примитивов в
документ
В следующем
упражнении вы получите некоторый опыт работы с
примитивами, добавив несколько общих примитивов
в документ Inventory Valid.xml, созданный вами в
лекции 5.
Добавьте примитивы в
документ
- В вашем текстовом
редакторе откройте документ Inventory
Valid.xml, созданный вами в разделе "Преобразование
корректно сформированного документа в
валидный" в лекции 5.
- В начало DTD
документа (блок текста, ограниченный
символами [] в верхней части документа)
добавьте следующие объявления примитива и
нотации:
<!-- примитивы для
присвоения значений элементу BINDING:
-->
<!ENTITY mass "mass market paperback">
<!ENTITY trade "trade paperback">
<!ENTITY hard "hardcover">
<!-- внешние примитивы, содержащие
обзоры -->
<!-- они будут присвоены атрибуту Review
элементов BOOK -->
<!NOTATION DOC SYSTEM "Microsoft Word
document">
<!NOTATION TXT SYSTEM "plain text file">
<!ENTITY rev_leaves
SYSTEM "Review Leaves of Grass.doc"
NDATA DOC>
<!ENTITY rev_faun1
SYSTEM "Review 01 of The Marble Faun.doc"
NDATA DOC>
<!ENTITY rev_faun2
SYSTEM "Review 02 of The Marble Faun.txt"
NDATA TXT>
<!ENTITY rev_screw
SYSTEM "Review of The Turn of the Screw.txt"
NDATA TXT>
Первые
три примитива представляют собой внутренние
разбираемые примитивы, которые вы можете
вставлять в элементы
BINDING, вместо того, чтобы вводить
описание типа переплета для каждого элемента.
Использование примитивов дает возможность
обеспечить однозначность ваших описаний
типов переплета для различных книг. Кроме
того, примитивы облегчают модификацию
описания. (Например, вы можете заменить
"hardcover" на "hardback" для каждого
элемента BINDING,
в котором встречается этот тип обложки,
простым редактированием примитива hard.)
Следующие (и последние) четыре примитива
представляют собой общие внешние не
разбираемые примитивы, которые позволяют вам
подключать внешние файлы, содержащие обзоры
книг для элементов
BOOK.
- Добавьте атрибут
Reviews в
объявление списка атрибутов для элемента
BOOK далее в
DTD следующим образом:
<!ATTLIST BOOK
InStock (yes | no)
#REQUIRED
Reviews ENTITIES #IMPLIED>
Reviews
представляет собой не обязательный атрибут (#IMPLIED),
которому вы можете присвоить имена одного
или нескольких общих внешних не разбираемых
примитивов. (Reviews имеет тип
ENTITIES).
- В каждом элементе
BINDING
замените описание переплета соответствующей
ссылкой на примитив. Например, вы должны
изменить элемент
BINDING для книги The Adventures of
Huckleberry Finn с
<BINDING>mass
market paperback</BINDING>
на
<BINDING>&mass;</BINDING>
- Добавьте атрибуты
Reviews элементам BOOK следующим образом:
- Для Leaves of
Grass:
<BOOK InStock="no"
Reviews="rev_leaves">
- Для The Marble
Faun:
<BOOK InStock="yes"
Reviews="rev_faun1 rev_faun2">
- Для The Turn
of the Screw:
<BOOK InStock="no"
Reviews="rev_screw">
- Чтобы отразить
новое имя файла, которое вы собираетесь
присвоить, измените комментарий в начале
документа с
<!-- Имя файла:
Inventory Valid.xml -->
на
<!-- Имя файла:
Inventory Valid Entity.xml -->
- Воспользуйтесь
командой Save As (Сохранить как) вашего
текстового редактора, чтобы сохранить копию
модифицированного документа под именем
Inventory Valid Entity.xml.
Полный
XML-документ представлен в Листинге 6.1.
<?xml version="1.0"?>
<!--Имя файла: Inventory Valid Entity.xml
-->
<!DOCTYPE INVENTORY
[
<!-- примитивы для присвоения значений элементу BINDING: -->
<!ENTITY mass "mass market paperback">
<!ENTITY trade "trade paperback">
<!ENTITY hard "hardcover">
<!-- внешние примитивы, содержащие обзоры -->
<!-- они будут присвоены атрибуту Review элементов BOOK -->
<!NOTATION DOC SYSTEM "Microsoft Word document">
<!NOTATION TXT SYSTEM "plain text file">
<!ENTITY rev_leaves SYSTEM "Review of Leaves of Grass.doc"
NDATA DOC>
<!ENTITY rev_faun1 SYSTEM "Review 01 of The Marble Faun.doc"
NDATA DOC>
<!ENTITY rev_faun2 SYSTEM "Review 02 of The Marble Faun.txt"
NDATA TXT>
<!ENTITY rev_screw SYSTEM "Review of The Turn of the Screw.txt"
NDATA TXT>
<!ELEMENT INVENTORY (BOOK)*>
<!ELEMENT BOOK (TITLE, AUTHOR, BINDING, PAGES, PRICE)>
<!ATTLIST BOOK InStock (yes|no) #REQUIRED
Reviews ENTITIES #IMPLIED>
<!ELEMENT TITLE (#PCDATA | SUBTITLE)*>
<!ELEMENT SUBTITLE (#PCDATA)>
<!ELEMENT AUTHOR (#PCDATA)>
<!ATTLIST AUTHOR Born CDATA #IMPLIED>
<!ELEMENT BINDING (#PCDATA)>
<!ELEMENT PAGES (#PCDATA)>
<!ELEMENT PRICE (#PCDATA)>
]
>
<INVENTORY>
<BOOK InStock="yes">
<TITLE>The Adventures of Huckleberry
Finn</TITLE>
<AUTHOR Born="1835">Mark Twain</AUTHOR>
<BINDING>&mass;</BINDING>
<PAGES>298</PAGES>
<PRICE>$5.49</PRICE>
</BOOK>
<BOOK InStock="no" Reviews="rev_leaves">
<TITLE>Leaves of Grass</TITLE>
<AUTHOR Born="1819">Walt Whitman</AUTHOR>
<BINDING>&hard;</BINDING>
<PAGES>462</PAGES>
<PRICE>$7.75</PRICE>
</BOOK>
<BOOK InStock="yes">
<TITLE>The Legend of Sleepy Hollow</TITLE>
<AUTHOR>Washington Irving</AUTHOR>
<BINDING>&mass;</BINDING>
<PAGES>98</PAGES>
<PRICE>$2.95</PRICE>
</BOOK>
<BOOK InStock="yes" Reviews="rev_faun1 rev_faun2">
<TITLE>The Marble Faun</TITLE>
<AUTHOR Born="1804">Nathaniel
Hawthorne</AUTHOR>
<BINDING>™</BINDING>
<PAGES>473</PAGES>
<PRICE>$10.95</PRICE>
</BOOK>
<BOOK InStock="no">
<TITLE>Moby-Dick
<SUBTITLE>Or, the
Whale</SUBTITLE>
</TITLE>
<AUTHOR Born="1819">Herman Melville</AUTHOR>
<BINDING>&hard;</BINDING>
<PAGES>724</PAGES>
<PRICE>$9.95</PRICE>
</BOOK>
<BOOK InStock="yes">
<TITLE>The Portrait of a Lady</TITLE>
<AUTHOR>Henry James</AUTHOR>
<BINDING>&mass;</BINDING>
<PAGES>256</PAGES>
<PRICE>$4.95</PRICE>
</BOOK>
<BOOK InStock="yes">
<TITLE>The Scarlet Letter</TITLE>
<AUTHOR>Nathaniel Hawthorne</AUTHOR>
<BINDING>™</BINDING>
<PAGES>253</PAGES>
<PRICE>$4.25</PRICE>
</BOOK>
<BOOK InStock="no" Reviews="rev_screw">
<TITLE>The Turn of the Screw</TITLE>
<AUTHOR>Henry James</AUTHOR>
<BINDING>™</BINDING>
<PAGES>384</PAGES>
<PRICE>$3.35</PRICE>
</BOOK>
</INVENTORY>
Листинг 6.1.
Inventory Valid Entity.xml
8. Если вы
хотите проверить валидность вашего документа,
воспользуйтесь сценарием проверки на валидность,
приведенным в разделе "Проверка валидности XML-документа"
в лекции 9.
|