Добавление DTD
Объявление типа документа представляет собой блок XML-разметки, который вы должны добавить в пролог валидного XML-документа. Он может располагаться в любом месте пролога – вне другой разметки – после XML-объявления, как показано на рисунке 5.1. (Напомним, что если вы включаете XML-объявление, оно должно располагаться в начале документа.)
Рис. 5.1.
Объявление типа документа определяет структуру документа. Если вы открываете документ, не содержащий объявления типа, в Internet Explorer 5, процессор Internet Explorer 5 всего лишь осуществляет проверку документа на корректность формы составления. Если же вы открываете документ, содержащий объявление типа документа, процессор Internet Explorer 5 будет проверять документ на валидность вместе с проверкой на корректность формы составления, так что ваш документ должен отвечать всем имеющимся декларациям в объявлении типа документа. Так, вы не сможете включить в документ какие-либо элементы или атрибуты, если вы не объявили их в объявлении типа документа. Каждый элемент и атрибут, который вы включаете, должен соответствовать спецификации (например, допустимости применения данного содержимого элемента или типа атрибута), выраженной в соответствующем объявлении.
Примечание. Процессор Internet Explorer 5 проверяет документ на валидность только в том случае, если вы открываете документ через HTML Web-страницу (с использованием техники, с которой вы познакомитесь в лекциях 8 и 9). Если вы открываете XML-документ непосредственно в Internet Explorer 5, процессор будет проверять документ (включая любое объявление типа документа, которое он содержит) на корректность формы составления, но не будет проверять документ на валидность, даже если он содержит объявление типа документа.
on_load_lecture()
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
вопросы | »
для печати и PDA
Курсы | Учебные программы | Учебники | Новости | Форум | Помощь
Телефон: +7 (495) 253-9312, 253-9313, факс: +7 (495) 253-9310, email: info@intuit.ru © 2003-2007, INTUIT.ru::Интернет-Университет Информационных Технологий - дистанционное образование |
Форма записи DTD
Объявление типа документа имеет следующую обобщенную форму записи:
<!DOCTYPE Имя DTD>
Здесь Имя указывает на имя элемента Документ. Имя действительного элемента Документ должно в точности соответствовать имени, записанному в объявлении. (Правила, в соответствии с которыми следует выбирать имена элементов, приведены в разделе "Анатомия элемента" в лекции 3.) Например, если вы создаете объявление типа документа для документа, рассмотренного в предыдущем разделе, вам следует использовать имя INVENTORY:
<!DOCTYPE INVENTORY DTD>
(Это еще не законченное объявление типа документа. DTD следует заменить реальным содержимым.)
DTD представляет собой определение типа документа, которое содержит объявления, задающие элементы документа, атрибуты и другие компоненты. В следующем разделе вы познакомитесь с формой записи их.
Примечание. Подобно всем ключевым словам XML, DOCTYPE должно быть набрано прописными буквами.
Форма записи объявления списка атрибутов
Объявление списка атрибутов имеет следующую общую форму:
<!ATTLIST Имя ОпрАтр>
Здесь Имя представляет собой имя элемента, ассоциированного с атрибутом или атрибутами. ОпрАтр – это одно или несколько определений атрибутов, каждое из которых определяет один атрибут.
Определение атрибута имеет следующую форму записи:
Имя ОпрАтр ОбъявУмолч
Здесь Имя представляет собой имя атрибута. (Правила выбора имен атрибутов приведены в разделе "Правила создания атрибутов" в лекции 3.)
ОпрАтр представляет собой тип атрибута, т.е. виды значений, которые могут быть присвоены атрибуту. (О типах атрибутов пойдет речь в следующем разделе.) ОбъявУмолч – это объявление по умолчанию, которое указывает на востребованность атрибута и содержит другую информацию. (Об этом будет рассказано далее в этой лекции.)
Допустим, вы объявили тип элемента с именем FILM следующим образом:
<!ELEMENT FILM (TITLE, (STAR | NARRATOR | INSTRUCTOR) )>
Вот пример объявления списка атрибутов, которое описывает два атрибута – Class и Year – для элемента FILM:
<!ATTLIST FILM Class CDATA "fictional" Year CDATA #REQUIRED>
На рисунке 5.3 представлены составные части этого объявления.
Рис. 5.3.
Вы можете присвоить атрибуту Class любую строку в кавычках (ключевое слово CDATA); если вы опускаете атрибут для определенного элемента, ему будет автоматически присвоено значение по умолчанию "fictional". Вы можете присвоить атрибуту Year любую строку в кавычках; этот атрибут, однако, должен быть обязательно присвоен для каждого элемента FILM (ключевое слово #REQUIRED), поэтому он не имеет значения по умолчанию.
Следующий полный XML-документ включает это объявление списка атрибутов, а также элемент FILM:
<?xml version="1.0"?> <!DOCTYPE FILM [ <!ELEMENT FILM (TITLE, (STAR | NARRATOR | INSTRUCTOR) )> <!ATTLIST FILM Class CDATA "fictional" Year CDATA #REQUIRED> <!ELEMENT TITLE (#PCDATA)> <!ELEMENT STAR (#PCDATA)> <!ELEMENT NARRATOR (#PCDATA)> <!ELEMENT INSTRUCTOR (#PCDATA)> ] > <FILM Year="1948"> <TITLE>The Morning After</TITLE> <STAR>Morgan Attenbury</STAR> </FILM>
Для элемента FILM атрибуту Year присвоено значение "1948". Атрибут Class опущен; однако, поскольку этот атрибут имеет значение по умолчанию ("fictional"), оно присваивается атрибуту, как если бы вы записали его в качестве значения атрибута.
Примечание. Если вы использовали для данного типа элемента более одного объявления списка атрибутов, содержания двух объявлений объединяются. Если атрибут с заданным именем объявлен для одного и того же элемента несколько раз, первое объявление используется, а последующие – игнорируются. (Множественные объявления списков атрибутов могут иметь место, если документ имеет как внутренние, так и внешние DTD, о чем пойдет речь далее в этой лекции.)
Форма записи объявления типа элемента
Объявление типа элемента имеет следующую обобщенную форму:
<!ELEMENT Имя опись_содержимого>
Здесь Имя есть имя объявляемого типа элемента. (Свод правил по правильному заданию имен элементов приведен в разделе "Анатомия элемента" в лекции 3.) Опись_содержимого – это описание содержимого, которое определяет, что может содержать элемент. В следующем разделе приведены различные типы описаний содержимого, которые вы можете использовать.
Ниже приведено объявление типа элемента с именем TITLE, для содержимого которого могут использоваться только символьные данные (дочерние элементы не допускаются):
<!ELEMENT TITLE (#PCDATA)>
А вот объявление для типа элемента с именем GENERAL, содержимое которого может быть любым:
<!ELEMENT GENERAL ANY>
В качестве последнего примера рассмотрим законченный XML-документ с двумя типами элементов. Объявление типа элемента COLLECTION указывает, что он может содержать один или несколько элементов CD, а объявление типа элемента CD указывает, что он может содержать только символьные данные. Заметим, что документ соответствует этим объявлениям, и, следовательно, является валидным:
<?xml version="1.0"?> <!DOCTYPE COLLECTION [ <!ELEMENT COLLECTION (CD)+> <!ELEMENT CD (#PCDATA)> <!-- Вы также можете включать комментарии в DTD. --> ] > <COLLECTION> <CD>Mozart Violin Concertos 1, 2, and 3</CD> <CD>Telemann Trumpet Concertos</CD> <CD>Handel Concerti Grossi Op. 3</CD> </COLLECTION> Примечание. Вы можете объявить определенный тип элемента в данном документе только один раз.
Использование и внешних, и внутренних подмножеств DTD
Чтобы использовать и внешнее и внутреннее подмножество DTD, следует использовать ключевое слово SYSTEM вместе с системным литералом, задающим местонахождение файла с внешним подмножеством DTD, после чего внутри квадратных скобок ([]) следует объявление разметки внутреннего подмножества DTD.
Вот пример простого XML-документа, имеющего как внутреннее, так и внешнее подмножество DTD:
<?xml version="1.0"?> <!DOCTYPE BOOK SYSTEM "Book.dtd" [ <!ATTLIST BOOK ISBN CDATA #IMPLIED Year CDATA "2000"> <!ELEMENT TITLE (#PCDATA)> ] > <BOOK Year="1998"> <TITLE>The Scarlet Letter</TITLE> </BOOK>
Вот содержимое файла Book.dtd, в котором хранится внешнее подмножество DTD:
<!ELEMENT BOOK ANY> <!ATTLIST BOOK ISBN NMTOKEN #REQUIRED>
Если вы используете внешнее и внутреннее подмножество DTD, XML-процессор объединяет их содержимое следующим образом:
в общем случае он осуществляет слияние двух подмножеств, чтобы сформировать полный DTD. В рассмотренном примере объединенный DTD определяет два элемента, TITLE и BOOK, а также два атрибута для элемента BOOK, ISBN и Year;однако в случае, если атрибут с одним и тем же именем и типом элемента объявляется более одного раза, XML-процессор использует первое объявление и игнорирует все последующие; (Это правило применимо и для повторных объявлений примитивов, о чем будет рассказано в лекции 6.)внутреннее подмножество DTD имеет приоритет перед внешним подмножеством DTD (даже если ссылка на внешнее подмножество идет первой в объявлении типа документа). Таким образом, любой атрибут (или примитив), определенный во внутреннем подмножестве, доминирует над атрибутом с тем же именем и типом элемента, объявленным во внешнем подмножестве. В примере XML-процессор считает, что атрибут ISBN имеет тип CDATA и объявление значения по умолчанию #IMPLIED, поэтому следующий элемент (в котором не указан ISBN) является корректным:
<BOOK Year="1850"> <TITLE>The Scarlet Letter</TITLE> </BOOK>
Примечание. Хотя XML- процессор просто игнорирует повторные объявления атрибутов и примитивов, повторное объявление элемента (даже если он объявлен тем же самым образом) является допустимым.
Способ объединения внутреннего и внешнего подмножеств DTD XML-процессором дает вам возможность использовать общий DTD (например такой, который используется для XML-приложений) в качестве внешнего подмножества DTD, а затем адаптировать (или субклассировать, как говорят программисты) DTD для конкретного документа путем включения внутреннего подмножества. Ваше внутреннее подмножество может добавлять элементы, атрибуты или примитивы – он также может изменять определения атрибутов или примитивов.
Использование только внешнего подмножества DTD
Чтобы использовать только внешнее подмножество DTD, опустите блок объявлений разметки, ограниченных квадратными скобками ([]), и вместо этого включите ключевое слово SYSTEM, после которого в кавычках должно следовать описание местонахождения отдельного файла, содержащего DTD. Рассмотрим, например, документ SIMPLE, используемый ранее в этой лекции и имеющий внутреннее подмножество DTD:
<?xml version="1.0"?> <!DOCTYPE SIMPLE [ <!ELEMENT SIMPLE ANY> ] > <SIMPLE> This is an extremely simplistic XML document. </SIMPLE>
Если в этом документе используется внешнее подмножество DTD, он будет иметь следующий вид:
<?xml version="1.0"?> <!DOCTYPE SIMPLE SYSTEM "Simple.dtd"> <SIMPLE> This is an extremely simplistic XML document. </SIMPLE>
Файл Simple.dtd должен иметь следующее содержимое:
<!ELEMENT SIMPLE ANY>
Файл, содержащий внешнее подмножество DTD, может включать любые объявления разметки, которые могут быть включены во внутреннее подмножество DTD (см. раздел "Создание DTD" ранее в этой лекции).
Описание местонахождения файла (в данном примере Simple.dtd) называется системным литералом. Он может быть заключен в одинарные (') или двойные (") кавычки и содержать любые символы, за исключением символов кавычек, используемых как ограничители.
Системный литерал задает унифицированный идентификатор ресурса (URI – uniform resource identifier) файла, содержащего внешнее подмножество DTD. В настоящее время URI практически аналогичен стандартному Internet-адресу, известному как унифицированный указатель ресурса (URL – Uniform Resource Locator). Вы можете использовать полностью прописанный URI, подобно следующему:
<!DOCTYPE SIMPLE SYSTEM " HYPERLINK "http://bogus.com/dtds/Simple.dtd" http://bogus.com/dtds/Simple.dtd">
Или, вы можете использовать частичный URI, который задает местонахождение относительно местонахождения XML-документа, содержащего URI, например:
<!DOCTYPE SIMPLE SYSTEM "Simple.dtd">Примечание. URI представляет собой чрезвычайно гибкую систему нотации для адресации ресурсов. Одним из типов URI является URL (Uniform Resource Locator), обычно используемый в Internet (например, http://bogus.com/documents/Simple.dtd. Аналогично, если бы XML-документ был расположен в HYPERLINK file:///C:\\XML ile:///C:\XML Step by Step\Example Code\Simple.xml, "Simple.dtd" ссылался бы на HYPERLINK file:///C:\\XML ile:///C:\XML Step by Step\Example Code\Simple.dtd.
Использование внешних подмножеств DTD
Описания типа документа, рассмотренные нами в этой лекции, полностью содержатся внутри объявления типа документа в составе документа. Такой тип DTD называется внутренним подмножеством DTD.
Вы также можете поместить все или часть DTD документа в отдельный файл, а затем ссылаться на этот файл из объявления типа документа. DTD – или часть DTD – содержащаяся в отдельном файле, называется внешним подмножеством DTD.
Примечание. Применение внешнего подмножества DTD имеет смысл главным образом для DTD, которые являются общими для целой группы документов. Каждый документ может ссылаться на один файл DTD (или копию этого файла) как на внешнее подмножество DTD. При этом вам не надо копировать содержимое DTD в каждый использующий его документ, а также облегчается внесение изменений в DTD. (Вам требуется модифицировать только файл DTD – и все копии этого файла – вместо того, чтобы редактировать все документы, которые его используют.) Как вам известно из лекции 1, многие стандартные XML-приложения основаны на общем DTD, включаемом во все XML-документы, отвечающие этому приложению. (См. разделы "Стандартные XML-приложения" и "Реальное использование XML" в лекции 1.)
Объявление атрибутов
В валидном XML-документе вы также должны исчерпывающе объявить все атрибуты, которые вы предполагаете использовать для элементов документа. Вы определяете все атрибуты, ассоциированные с определенным элементом, с помощью специального типа DTD-разметки, называемого объявлением списка атрибутов. Это объявление:
определяет имена атрибутов, ассоциированных с элементом. В валидном документе вы можете включить в начальный тег элемента только те атрибуты, которые определены для элемента;устанавливает тип данных каждого атрибута;задает востребованность для каждого атрибута. Если атрибут не востребован, в объявлении списка атрибутов указывается, что должен делать процессор, если атрибут опущен. (В объявлении должно, например, содержаться значение атрибута по умолчанию, которое будет использовать процессор.)
Объявление типов элементов
В валидном XML-документе вы должны полностью объявить тип каждого элемента, который вы используете в документе, в объявлении типа элемента внутри DTD. Объявление типа элемента указывает на имя типа элемента и допустимое содержимое элемента (часто описывающее порядок размещения дочерних элементов). Как единое целое, объявление типа элемента в DTD – подобно построению базы данных – задает полную логическую структуру документа. Таким образом, объявление типа элемента указывает на типы элементов, которые содержит документ, порядок следования элементов, а также описание содержимого элементов.
Объявление значения по умолчанию
Объявление значения по умолчанию – это третий и последний обязательный компонент в определении атрибута. Оно задает, является ли атрибут обязательным, и если нет, указывает, что должен предпринимать процессор в случае, когда атрибут опущен (см. рис. 5.5). Так, объявление должно обеспечить значение атрибута по умолчанию, которое будет использовать процессор в том случае, если атрибут отсутствует.
Рис. 5.5.
Объявление значения по умолчанию может иметь следующие четыре формы:
#REQUIRED. При этой форме вы должны задать значение атрибута для каждого элемента ассоциированного типа. Например, следующее объявление указывает, что вы должны присвоить значение атрибуту Class внутри начального тега каждого элемента FILM в документе: <!ATTLIST FILM Class CDATA #REQUIRED>
#IMPLIED. Эта форма указывает, что вы можете либо включить, либо опустить атрибут для элемента ассоциированного типа, а также, что если вы опускаете атрибут, то никакое значение по умолчанию процессору не передается. (Эта форма "подразумевает", а не "устанавливает" значение, позволяя приложению использовать свое собственное значение по умолчанию – т.е. имя.) Например, следующее объявление указывает, что присвоение значения атрибуту Class внутри элемента FILM является не обязательным, и что в документе не представлено значение Class по умолчанию: <!ATTLIST FILM Class CDATA #IMPLIED>
AttValue, где AttValue – значение атрибута по умолчанию. При такой форме вы можете либо включить, либо опустить атрибут для элемента ассоциированного типа. Если вы опускаете атрибут, процессор использует значение по умолчанию, как если бы вы включили атрибут и задали это значение.
Задаваемое значение по умолчанию, конечно, должно соответствовать заданному типу атрибута. Например, следующее объявление присваивает значение по умолчанию "fictional" атрибуту Class:
<!ATTLIST FILM Class CDATA "fictional">
Согласно этому объявлению следующие два элемента эквивалентны:
<FILM>The Graduate</FILM> <FILM Class="fictional">The Graduate</FILM>
#FIXED AttValue, где AttValue – значение атрибута по умолчанию. При такой форме вы можете либо включать, либо опускать атрибут для элемента ассоциированного типа. Если вы опускаете атрибут, процессор будет использовать значение, заданное по умолчанию; если вы включаете атрибут, вы должны задать значение по умолчанию. (Поскольку вы можете задать только значение по умолчанию, нет смысла включать в элемент описание атрибута, за исключением желания сделать документ более понятным для восприятия.) Например, следующее объявление присваивает фиксированное значение по умолчанию атрибуту Class: <!ATTLIST FILM Class CDATA #FIXED "documentary">
В соответствии с этим объявлением следующие два эквивалентных элемента будут корректными:
<FILM>The Making of XML</FILM> <FILM Class="documentary">The Making of XML</FILM>
в то время как следующий элемент будет некорректным:
<!-- Некорректный элемент! --> <FILM Class="instructional">The Making of XML</FILM>
Описание содержимого элемента
Вы можете описать содержимое элемента – т.е. заполнить часть опись_содержимого в объявлении типа элемента – четырьмя различными способами.
Пустое содержимое (EMPTY). Ключевое слово EMPTY указывает, что элемент должен быть пустым – т.е. не может иметь содержимого. Например: <!ELEMENT IMAGE EMPTY>
Ниже приведены валидные элементы IMAGE, которые вы можете поместить в документ:
<IMAGE></IMAGE> <IMAGE />
Любое содержимое (ANY). Ключевое слово ANY указывает, что элемент может иметь любое допустимое для этого типа содержимое. То есть элемент этого типа может содержать или не содержать дочерние элементы в любом порядке и с любым количеством вхождений, иметь или не иметь чередующиеся символьные данные. Это наиболее неопределенный тип описания содержимого и дает возможность создавать типы элементов без ограничений на их содержимое. Вот пример соответствующего объявления: <!ELEMENT MISC ANY>
Содержимое элемента (также называемое дочернее содержимое). При таком описании типа содержимого элемент может содержать дочерние элементы, но не может непосредственно содержать символьные данные. Об этой возможности будет говориться в следующем разделе.Смешанное содержимое. При этом описании типа содержимого элемент может содержать любое количество смешанных данных, в том числе и чередующихся с дочерними элементами определенных типов. Эта возможность будет описана далее в данной лекции.
on_load_lecture()
« |
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
вопросы | »
для печати и PDA
Курсы | Учебные программы | Учебники | Новости | Форум | Помощь
Телефон: +7 (495) 253-9312, 253-9313, факс: +7 (495) 253-9310, email: info@intuit.ru © 2003-2007, INTUIT.ru::Интернет-Университет Информационных Технологий - дистанционное образование |
Основной критерий для валидного документа
Каждый XML-документ должен быть корректно сформированным, т.е. отвечать минимальным требованиям по составлению XML-документа. Если документ не является корректно сформированным, он не может считаться XML-документом.
Корректно сформированный XML-документ также может быть валидным. Валидным (valid) называется корректно сформированный (well-formed) документ, отвечающий двум дополнительным требованиям:
пролог документа должен содержать специальное объявление типа документа, которое содержит определение типа документа (DTD), задающее структуру документа;остальной документ должен отвечать структуре, заданной в DTD.
В последующих разделах этой лекции, а также в лекции 6, вы узнаете, как создавать документы, отвечающие этим двум общим требованиям.
Преимущества использования валидных XML-документов
Может показаться, что при создании валидного XML-документа выполняется ряд лишних действий: вы должны сначала полностью описать структуру документа в DTD, а затем создать сам документ, отвечающий всем спецификациям, содержащимся в DTD. Может сложиться впечатление, что гораздо проще непосредственно добавлять любые необходимые элементы и атрибуты, как вы это делали в примерах, работая с корректно сформированными документами в предыдущих лекциях.
Однако, если вы хотите быть уверенным, что ваш документ отвечает определенной структуре или набору стандартов, включение DTD, которое описывает эту структуру, дает возможность XML-процессору (например, Microsoft Internet Explorer 5) проверить, соответствует ли документ структуре. Другими словами, DTD обеспечивает стандартный шаблон для процессора, чтобы при проверке валидности он мог следовать требуемой структуре и гарантировать, что ваш документ соответствует установленным стандартам. Если какая-либо часть документа не отвечает DTD-спецификации, процессор может отобразить сообщение об ошибке, чтобы вы могли отредактировать документ и исправить несоответствия.
Использование валидных документов особенно полезно для проверки однородности среди группы схожих документов. Фактически, стандарт XML определяет DTD как "грамматику для определенного класса документов".
Предположим, компании, занимающейся публикацией в Web, требуется, чтобы все ее редакторы создавали XML-документы, отвечающие единой структуре. Создание одного DTD и включение его во все документы может обеспечить условия соответствия документов требуемой структуре, в то время как редакторы будут избавлены от необходимости добавлять новые элементы, помещать информацию в неправильном порядке, присваивать неправильные типы данных и т.д. Конечно, валидность документа должна быть проверена при его обработке процессором.
Включение DTD и проверка валидности имеют особое значение, если документ будет обрабатываться программой пользователя, ориентированной на определенную структуру документа. Если все пользователи программного обеспечения включат в свои XML-документы соответствующие DTD, и все документы пройдут проверку на валидность, то пользователи могут быть уверены, что их документы будут распознаны программой-обработчиком. Например, если группа математиков создает математические документы, которые будут отображаться специальной программой, все они могут включить в свои документы одинаковые DTD, которые содержат определения требуемой структуры, элементов, атрибутов и других компонентов.
На деле большинство реальных XML-приложений, список которых приведен в конце лекции 1, например, MathML, состоят из стандартного DTD, которое все пользователи приложения включают в свои XML-документы, чтобы при проверке валидности обеспечивалось соответствие структуре приложения, и документы были распознаны любой программой, разработанной для этого приложения.
Совет. Если вы открываете XML-документ (самостоятельный или с присоединенной таблицей стилей) непосредственно в Internet Explorer 5, процессор Internet Explorer 5 проверяет весь документ (в том числе объявление типа документа, если оно присутствует) на корректность формы составления, и выводит сообщение о фатальной ошибке при любом обнаруженном несоответствии. Однако процессор Internet Explorer 5 не проверяет документ на валидность.
Чтобы проверить документ на валидность, вы можете использовать сценарий проверки на валидность, приведенный в лекции 9 в разделе "Проверка валидности XML-документа". Вы можете прочесть приведенные в этом разделе указания сейчас, чтобы иметь возможность осуществлять проверку на валидность создаваемых вами XML-документов.
Преобразование корректно сформированного документа в валидный
В этом разделе вы попытаетесь на практике применить полученные при изучении этой лекции знания, преобразовав корректно сформированный документ в валидный. Вы модифицируете документ Inventory.xml, созданный вами в лекции 2, чтобы сделать его валидным. Вы также добавите новый элемент и два атрибута, чтобы освоить описанные в этой лекции приемы.
Сделаем документ валидным
- В вашем текстовом редакторе откройте документ Inventory.xml, созданный вами в лекции 2.Непосредственно перед элементом Документ – с именем INVENTORY – введите следующее объявление типа документа:
<![INCLUDE[ <!-- необязательный блок объявлений разметки, который временно восстановлен --> <!ATTLIST BOOK Category CDATA "fiction"> <!ELEMENT TITLE (#PCDATA)> <!ELEMENT AUTHOR (#PCDATA) ]]>
Совет. При выполнении модификации в ходе данного упражнения вы можете ориентироваться на полностью модифицированный документ, который приведен в Листинге 5.1 в конце этой лекции.
Обратите внимание, что имя следующего за DOCTYPE ключевого слова совпадает с именем элемента Документ, INVENTORY. DTD состоит только из внутреннего подмножества, которое определяет элементы и атрибуты документа следующим образом:
элемент Документ, INVENTORY, имеет содержимое. Он может включать ни одного или несколько дочерних элементов BOOK;элемент BOOK также имеет содержимое. Оно должно включать строго по одному из следующих элементов, в порядке, перечисленном в объявлении документа: TITLE, AUTHOR, BINDING, PAGES и PRICE;элемент TITLE имеет смешанное содержимое. Он может включать символьные данные вместе с ни одним или с несколькими элементами SUBTITLE;элементы AUTHOR, BINDING, PAGES и PRICE также имеют смешанное содержимое. Эти элементы, однако, могут включать только символьные данные без дочерних элементов;элемент BOOK имеет атрибут нумерованного типа с именем InStock, который является обязательным атрибутом и может принимать значения либо "yes", либо "no";элемент AUTHOR имеет атрибут строкового типа с именем Born, который является не обязательным и не имеет значения по умолчанию.
Добавьте следующий дочерний элемент SUBTITLE в элемент TITLE для книги Моби-Дик:
<BOOK> <TITLE>Moby-Dick <SUBTITLE>Or, the Whale</SUBTITLE> </TITLE>
Добавьте обязательный атрибут InStock каждому элементу BOOK, присвоив ему значения "yes" или "no", как показано ниже:
<BOOK InStock="yes"> <TITLE>The Adventures of Huckleberry Finn</TITLE> <AUTHOR>Mark Twain</AUTHOR> <BINDING>mass market paperback</BINDING> <PAGES>298</PAGES> <PRICE>$5.49</PRICE> </BOOK>
Добавьте не обязательный элемент Born к одному или нескольким элементам. Хотя вы можете присвоить этому атрибуту любую синтаксически правильную строку в кавычках, в данном случае он должен хранить дату рождения автора. Пример: <AUTHOR Born="1835">Mark Twain</AUTHOR>
Чтобы отразить новое имя файла, которое вы собираетесь присвоить, измените комментарий в начале документа с: <!-- Имя файла: Inventory.xml -->
на
<!-- Имя файла: Inventory Valid.xml -->
Воспользуйтесь командой Save As (Сохранить как) вашего текстового редактора, чтобы сохранить копию модифицированного документа под именем Inventory Valid.xml.
Законченный документ представлен в Листинге 5.1.
Листинг 5.1. Parts.xml (html, txt)
Если вы хотите проверить валидность вашего документа, воспользуйтесь сценарием проверки XML-документа на валидность, приведенным в разделе "Проверка валидности XML-документа" в лекции 9.
Создание DTD
DTD состоит из символа левой квадратной скобки ([), после которой следует ряд объявлений разметки, заканчивающихся правой квадратной скобкой (]). Объявления разметки описывают логическую структуру документа; т.е. задают элементы документа, атрибуты и другие компоненты. На рисунке 5.2 приведен законченный валидный XML-документ, содержащий DTD с единственным объявлением разметки, которое определяет один тип элемента в документе, SIMPLE.
Рис. 5.2.
DTD в этом примере документа указывает, что документ может содержать только элементы типа SIMPLE (это единственный заданный тип элемента), и что элемент SIMPLE может иметь любое допустимое для данного типа содержимое (ключевое слово ANY).
DTD может содержать следующие типы объявлений разметки.
Объявления типов элементов. Они определяют типы элементов, которые может содержать документ, а также содержимое и порядок следования элементов. Об объявлениях типов элементов пойдет речь в следующем разделе.Объявления списков атрибутов. Каждое объявление списков атрибутов задает имена атрибутов, которые могут быть использованы с определенным типом элемента, а также типы данных и устанавливаемые по умолчанию значения этих атрибутов. Об этих объявлениях будет рассказано далее в этой лекции.Объявления примитивов. Вы можете использовать примитивы для хранения часто используемых фрагментов текста или для встраивания не относящихся к XML данных в ваш документ. Об объявлениях примитивов будет рассказано в лекции 6.Объявления нотаций. Нотация описывает формат данных или идентифицирует программу, используемую для обработки определенного формата. Об объявлениях нотаций пойдет речь в лекции 6.Инструкции по обработке. Эта тема затрагивалась в разделе "Использование инструкций по обработке" в лекции 4.Комментарии. О них говорилось в разделе "Добавление комментариев" в лекции 4.Ссылки на параметрические примитивы. Любой из приведенных выше компонентов может содержаться внутри параметрического примитива и добавляться путем ссылки на параметрический примитив. Смысл этого оператора станет вам понятен, когда вы познакомитесь с материалом из лекции 6. Данный пункт приведен здесь для полноты картины.Примечание. Типы DTD, обсуждаемые в этом разделе (и используемые в примерах в последующих разделах) относятся к внутреннему подмножеству DTD, поскольку полностью включаются в объявление типа данного документа. В конце этой лекции вы узнаете, как использовать DTD, размещенные в отдельном файле, и относящиеся к внешнему подмножеству DTD.
Тип атрибута
Тип атрибута является вторым необходимым компонентом в определении атрибута. Он задает вид значений, которые вы можете присваивать атрибуту внутри документа, как показано на рисунке 5.4.
Рис. 5.4.
Вы можете задавать тип атрибута тремя различными способами.
Строковый тип. Строковый тип атрибута может быть назначен любой строке в кавычках (литералу), которая отвечает общим правилам, описанным в разделе "Правила для корректного задания значений атрибутов" в лекции 3. Вы должны объявить строковый тип атрибута с использованием ключевого слова CDATA, как это сделано для определения атрибута Class в следующем примере: <!ATTLIST FILM Class CDATA "fictional">Маркерный тип. Значения, которые вы можете присваивать атрибуту маркерного типа, имеют ряд ограничений (см. следующий раздел).Нумерованный тип. Для нумерованного типа атрибута вы можете присваивать одно значение или список определенных значений. Об этом типе вы узнаете в разделе "Задание нумерованных типов" далее в этой лекции.
Требования корректности формирования и валидности
Требования корректности формирования представляют собой набор правил, определенных в спецификации XML, которым вы должны следовать – в дополнение к основным синтаксическим требованиям – чтобы создать правильно составленный документ. Поскольку XML-документ должен быть корректно сформированным, любое отклонение от требований корректности формирования считается фатальной ошибкой (fatal error). Если XML-процессор сталкивается с фатальной ошибкой, он должен остановить нормальную обработку документа и не пытаться ее возобновить.
Требования валидности представляют собой дополнительный набор правил в спецификации XML, которым вы должны следовать, чтобы создать валидный документ. Поскольку валидность является не обязательной для XML-документа, отклонение от требований валидности считается лишь ошибкой (error), но не фатальным сбоем. Если XML-процессор встречает ошибку, он может просто выдать сообщение о ней и продолжить выполнение обработки. Требования валидности состоят из специальных правил по созданию соответствующего объявления типа с его DTD, а также созданию документа, отвечающего описанию внутри вашего DTD.
Условия игнорирование разделов внешнего подмножества DTD
Вы можете заставить XML-процессор игнорировать часть внешнего подмножества DTD с помощью раздела IGNORE. Вы можете, например, использовать раздел IGNORE при разработке документа с целью временного отключения альтернативного или необязательного блока объявлений разметки. При этом вам не нужно удалять строки, а затем повторно их вставлять. (Если вы программист, то вам известно, что такой прием подобен "комментированию" фрагмента кода, который вы хотите временно игнорировать.) Раздел IGNORE начинается с символов <![IGNORE[ и заканчивается символами ]]>.
На рисунке 5.6 представлен пример полного описания внешнего подмножества DTD, включающего раздел IGNORE.
Рис. 5.6.
Если вы хотите временно восстановить блок объявлений разметки в разделе IGNORE, вам достаточно просто заменить ключевое слово IGNORE на INCLUDE, не удаляя при этом символы-ограничители (<![, [ и ]]>), как в следующем примере:
<![INCLUDE[ <!-- необязательный блок объявлений разметки, который временно восстановлен --> <!ATTLIST BOOK Category CDATA "fiction"> <!ELEMENT TITLE (#PCDATA)> <!ELEMENT AUTHOR (#PCDATA) ]]>
Впоследствии вы можете снова быстро отключить раздел, вернув заголовок IGNORE. Раздел INCLUDE, вложенный в раздел IGNORE, также игнорируется.
Примечание. Вы можете использовать разделы IGNORE и INCLUDE только во внешнем подмножестве DTD, либо во внешнем параметрическом примитиве. (Внешний параметрический примитив ссылается на отдельный файл, который – подобно внешнему подмножеству DTD – содержит объявления разметки, подробнее об этом вы узнаете в лекции 6.)
Задание маркерного типа
Как и любое значение атрибута, значение, которое вы присваиваете маркерному типу атрибута, должно представлять собой строку в кавычках, отвечающую общим правилам, описанным в разделе "Правила для корректного задания значений атрибутов" в лекции 3.
Кроме того, значение должно отвечать определенному ограничению, которое вы задаете в описании атрибута с помощью соответствующего ключевого слова. Например, в приведенном ниже XML-документе для атрибута StockCode определен маркерный тип с использованием ключевого слова ID. (ID – это только одно из ключевых слов, которые вы можете использовать для объявления маркерного типа.) Это ключевое слово означает, что для каждого элемента атрибуту должно быть присвоено уникальное значение. (Например, присвоение товарного кода "S021" двум элементам ITEM не допускается.)
<?xml version="1.0"?> <!DOCTYPE INVENTORY [ <!ELEMENT INVENTORY (ITEM*)> <!ELEMENT ITEM (#PCDATA)> <!ATTLIST ITEM StockCode ID #REQUIRED> ] > <INVENTORY> <!-- Каждый элемент ITEM должен иметь свое значение кода StockCode --> <ITEM StockCode="S021">Peach Tea Pot</ITEM> <ITEM StockCode="S034">Electric Cofee Grinder</ITEM> <ITEM StockCode="S086">Candy Thermometer</ITEM> </INVENTORY>
Ниже приведен полный список ключевых слов, которые вы можете использовать в определении маркерных типов атрибутов, и ограничения, которые они накладывают на значения атрибутов.
ID. Для каждого элемента атрибут должен иметь уникальное значение. Значение должно начинаться с буквы или символа подчеркивания (_), за которыми могут идти или не идти другие буквы, цифры, символы точки (.), тире (–) или символы подчеркивания. Данный тип элемента может иметь только один атрибут типа ID, а в объявлении значения атрибута по умолчанию должно фигурировать #REQUIRED или #IMPLIED (см. в разделе "Объявление значения по умолчанию" далее в этой лекции). Пример этого типа атрибута содержится в приведенном выше документе INVENTORY.IDREF. Значение атрибута должно совпадать со значением атрибута элемента типа ID внутри документа. Другими словами, этот тип атрибута является ссылкой на уникальный идентификатор другого атрибута. Например, вы можете добавить атрибут IDREF с именем GoesWith к элементу ITEM:
<!ELEMENT ITEM (#PCDATA)> <!ATTLIST ITEM StockCode ID #REQUIRED GoesWith IDREF #IMPLIED>
Далее вы можете использовать этот атрибут для ссылки на другой элемент ITEM:
<ITEM StockCode="S034">Electric Cofee Grinder</ITEM> <ITEM StockCode="S047" GoesWith="S034"> Cofee Grinder Brush </ITEM>
IDREFS. Этот тип атрибута похож на тип IDREF, но при этом значение может включать ссылки на несколько идентификаторов – разделенных пробелами – внутри строки в кавычках. Например, если вы назначите атрибуту GoesWith тип IDREFS таким образом: <!ATTLIST ITEM StockCode ID #REQUIRED GoesWith IDREFS #IMPLIED>
то можете использовать его на ссылки на несколько других элементов:
<ITEM StockCode="S034">Electric Cofee Grinder</ITEM> <ITEM StockCode="S039"> 1 pound Breakfast Blend Cofee Beans </ITEM> <ITEM StockCode="S047" GoesWith="S034 S039"> Cofee Grinder Brush </ITEM>
ENTITY. Значение атрибута должно совпадать с именем примитива, объявленного в DTD. Этот примитив не обрабатывается синтаксическим анализатором и ссылается на внешний файл, обычно содержащий не XML-данные. О таких примитивах будет рассказано в лекции 6.
Например, в DTD вы объявляете элемент с именем IMAGE, представляющий графическое изображение, и атрибут типа ENTITY с именем Source, указывающий на источник графических данных:
<!ELEMENT IMAGE EMPTY> <ATTLIST IMAGE Source ENTITY #REQUIRED>
Если вы объявили не анализируемый примитив с именем Logo (используя технику, с которой вы познакомитесь в лекции 6), который содержит графические данные для изображения, вы можете присвоить этот примитив атрибуту Source элемента IMAGE в документе следующим образом:
<IMAGE Source="Logo" />
ENTITIES. Этот тип атрибута похож на тип ENTITY, за исключением того, что значение может содержать имена нескольких не анализируемых примитивов – разделенных пробелами – внутри строки в кавычках. Например, если вы назначили атрибуту Source тип ENTITIES следующим образом:
<!ELEMENT IMAGE EMPTY> <!ATTLIST IMAGE Source ENTITIES #REQUIRED>
то сможете использовать его для ссылки на несколько не анализируемых примитивов (допустим, примитивов, содержащих графические данные в альтернативных форматах), например, так:
<IMAGE Source="LogoGif LogoBmp" />
(Здесь подразумевается, что LogoGif и LogoBmp – имена не анализируемых примитивов, которые были объявлены в DTD с помощью приемов, с которыми вы познакомитесь в лекции 6.)
NMTOKEN. Это значение есть элементарное имя (name token), представляющее собой имя, состоящее из одной или более букв, цифр, точек (.), тире (–) или символов подчеркивания (_). Элементарное имя может также содержать двоеточие (:), но не на первом месте. Например, если вы назначите атрибуту ISBN тип NMTOKEN следующим образом:
<!ELEMENT BOOK (#PCDATA)> <!ATTLIST BOOK ISBN NMTOKEN #REQUIRED>
то можете присвоить ему значение, начинающееся с цифры (цифры в качестве первых символов допустимы для типов NMTOKEN и NMTOKENS, но не для любых других маркерных типов):
<BOOK ISBN="9-99999-999-9">The Portrait of a Lady</BOOK>
NMTOKENS. Этот тип атрибута похож на тип NMTOKEN, но значение может содержать несколько элементарных имен – разделенных пробелами – внутри строки в кавычках. Например, если вы назначите атрибуту Codes тип NMTOKENS следующим образом:
<!ELEMENT SHIRT (#PCDATA)> <!ATTLIST SHIRT Codes NMTOKENS #REQUIRED>
вы можете присвоить ему несколько значений в виде элементарных имен:
<SHIRT Codes="38 21 97">long sleeve Henley</SHIRT>
Задание нумерованных типов
Как любое значение атрибута, значение, которое вы присваиваете нумерованному типу, должно представлять собой строку в кавычках, отвечающую правилам, описанным в разделе "Правила для корректного задания значений атрибутов" в лекции 3. Помимо этого, значение должно совпадать с одним из имен, приведенных в списке типов атрибутов. Эти имена могут иметь одну из следующих двух форм записи.
Открывающая скобка, вслед за которой идет список элементарных имен, разделенных символами | , после чего следует закрывающая скобка. Напомним, что элементарное имя – это имя, состоящее из одной или нескольких букв, цифр, точек (.), тире (–) или символов подчеркивания (_), а также может включать одно двоеточие (:), но не на первом месте. Например, если вы хотите ограничить значения атрибута Class словами "fictional", "instructional" или "documentary", то можете определить это атрибут как нумерованный тип следующим образом:
<!ATTLIST FILM Class (fictional | instructional | documentary) "fictional"
Вот законченный XML-документ, демонстрирующий использование атрибута Class:
<?xml version="1.0"?> <!DOCTYPE FILM [ <!ELEMENT FILM (TITLE, (STAR | NARRATOR | INSTRUCTOR) )> <!ATTLIST FILM Class (fictional | instructional | documentary) "fictional"> <!ELEMENT TITLE (#PCDATA) <!ELEMENT STAR (#PCDATA) <!ELEMENT NARRATOR (#PCDATA) <!ELEMENT INSTRUCTOR (#PCDATA) ] > <FILM Class="instructional"> <TITLE>The Use and Care of XML</TITLE> <NARRATOR>Michael Young</NARRATOR> </FILM>
Если вы опустили атрибут Class, ему будет по умолчанию присвоено значение "fictional". Присвоение атрибуту Class значения, отличного от "fictional", "instructional" или "documentary" приведет к ошибке.
Ключевое слово NOTATION, за которым идет пробел, затем открывающая скобка, затем список имен нотаций, разделяемых символами | , после чего следует закрывающая скобка. Каждое из этих имен должно точно соответствовать имени нотации, объявленному в DTD. Нотация описывает формат данных или идентифицирует программу, применяемую для обработки определенного формата (подробнее о нотациях будет рассказано в лекции 6).
Например, в вашем DTD объявлены нотации HTML, SGML и RTF. Тогда вы можете ограничить значения атрибута Format одним из этих имен нотаций с помощью следующего объявления:
<!ELEMENT EXAMPLE_DOCUMENT (#PCDATA)> <!ATTLIST EXAMPLE_DOCUMENT Format NOTATION (HTML | SGML | RTF) #REQUIRED>
В дальнейшем вы можете использовать элемент Format для указания формата определенного элемента EXAMPLE_DOCUMENT, как в следующем примере:
<EXAMPLE_DOCUMENT Format="HTML"> <![CDATA[ <HTML> <HEAD> <TITLE>Mike’s Home Page</TITLE> </HEAD> <BODY> <P>Welcome!</P> </BODY> </HTML> ]]> </EXAMPLE_DOCUMENT>
Присвоение атрибуту Format значения, отличного от "HTML", "SGML" или "RTF", приведет к ошибке. (Обратите внимание на использование здесь раздела CDATA – при этом вы можете свободно использовать символ левой угловой скобки (<) внутри символьных данных элемента.)
Задание смешанного содержимого
Если элемент имеет смешанное содержимое, он может включать символьные данные. Если же вы зададите в объявлении один или несколько типов дочерних элементов, он может содержать любые из этих дочерних элементов в любом порядке и с любым количеством вхождений (нуль и более). Другими словами, при смешанном содержимом вы можете задавать типы дочерних элементов, но не можете задавать порядок или количество вхождений дочерних элементов, а также задавать обязательность включения для определенных типов дочерних элементов.
Чтобы объявить тип элемента смешанного содержимого, вы можете воспользоваться одной из следующих форм модели содержимого.
Только символьные данные. Чтобы объявить тип элемента, который может содержать только символьные данные, используйте модель содержимого (#PCDATA). Так, следующее объявление указывает, что для элемента SUBTITLE допускаются только символьные данные: <!ELEMENT SUBTITLE (#PCDATA)>
Следующие два элемента в соответствии с данной декларацией являются корректными:
<SUBTITLE>A New Approach</SUBTITLE> <SUBTITLE></SUBTITLE>
Заметим, что элемент, который в соответствии с объявлением должен содержать символьные данные, может и не иметь никаких символов – т.е. быть пустым.
Примечание. Ключевое слово PCDATA относится к синтаксически анализируемым (разбираемым) символьным данным. Из лекции 3 вам известно, что XML-процессор синтаксически разбирает символьные данные внутри элемента – т.е. сканирует элемент в поиске XML-разметки. В связи с этим вы не можете использовать левую угловую скобку (<) или знак амперсанда (&) или символы ]]> как часть символьных данных, поскольку синтаксический анализатор будет интерпретировать каждый из этих символов или группы символов как разметку. Однако вы можете использовать любые символы с помощью ссылки на символ или на предопределенный примитив (см. лекцию 6), либо с помощью раздела CDATA (см. лекцию 4).
Символьные данные с необязательными дочерними элементами. Чтобы объявить тип элемента, который может содержать символьные данные плюс ни одного или несколько дочерних элементов, перечислите каждый тип дочернего элемента после ключевого слова PCDATA в модели содержимого, разделяя их символами ( и помещая звездочку (*) в конце всей модели содержимого. Каждое имя элемента может появляться в модели содержимого только один раз. Например, следующее объявление указывает, что элемент TITLE может содержать символьные данные плюс ни одного или несколько дочерних элементов SUBTITLE: <!ELEMENT TITLE (#PCDATA | SUBTITLE)*>
В соответствии с этим объявлением следующие элементы TITLE являются допустимыми:
<TITLE> Moby-Dick <SUBTITLE>Or, the Whale</SUBTITLE> </TITLE> <TITLE> <SUBTITLE>Or, the Whale</SUBTITLE> Moby-Dick </TITLE> <TITLE> Moby-Dick </TITLE> <TITLE> <SUBTITLE>Or, the Whale</SUBTITLE> <SUBTITLE>Another Subtitle</SUBTITLE> </TITLE> <TITLE></TITLE>
Задание содержимого элемента
Если элемент имеет содержимое, он может непосредственно содержать только определенные дочерние элементы, но не символьные данные. В тексте документа вы можете разделять дочерние элементы пробелами, чтобы улучшить восприятие документа, но процессор будет игнорировать символы пробела и не передаст их приложению.
Рассмотрим следующий пример XML-документа, описывающий одну книгу:
<?xml version="1.0"?> <!DOCTYPE BOOK [ <!ELEMENT BOOK (TITLE, AUTHOR)> <!ELEMENT TITLE (#PCDATA)> <!ELEMENT AUTHOR (#PCDATA)> ] > <BOOK> <TITLE>The Scarlet Letter</TITLE> <AUTHOR>Nathaniel Hawthorne</AUTHOR> </BOOK>
В этом документе тип элемента BOOK объявлен как имеющий содержимое элемента. (TITLE, AUTHOR), следующие за именем элемента в объявлении, составляют модель содержимого. Модель содержимого указывает на разрешенные типы дочерних элементов и их порядок. В этом примере модель содержимого указывает на то, что элемент BOOK должен иметь ровно один дочерний элемент TITLE, за которым следует ровно один дочерний элемент AUTHOR. При обработке документа процессор игнорирует три пустых строки, используемые для разделения дочерних элементов внутри элемента BOOK.
Модель содержимого может иметь одну из следующих основных форм.
Последовательная. Последовательная форма модели содержимого указывает, что элемент должен иметь заданную последовательность дочерних элементов. Вы отделяете имена типов дочерних элементов запятыми. Например, следующее DTD указывает, что элемент MOUNTAIN должен иметь один дочерний элемент NAME, после которого идет один дочерний элемент HEIGHT, за которым следует один дочерний элемент STATE:
<!DOCTYPE MOUNTAIN [ <!ELEMENT MOUNTAIN (NAME, HEIGHT, STATE)> <!ELEMENT NAME (#PCDATA)> <!ELEMENT HEIGHT (#PCDATA)> <!ELEMENT STATE (#PCDATA)> ] >
Следовательно, следующий элемент Документ будет валидным:
<MOUNTAIN> <NAME>Wheeler</NAME> <HEIGHT>13161</HEIGHT> <STATE>New Mexico</STATE> </MOUNTAIN>
Следующий элемент Документ, однако, не будет валидным, поскольку порядок дочерних элементов не соответствует объявленному:
<MOUNTAIN> <!-- Неправильный элемент! --> <STATE>New Mexico</STATE> <NAME>Wheeler</NAME> <HEIGHT>13161</HEIGHT> </MOUNTAIN>
Пропуск дочернего элемента или использование одного и того же типа дочернего элемента более одного раза также недопустимо. Как вы видите, это достаточно строгий вид объявления.
Выборочная. Выборочная форма модели содержимого указывает, что элемент может иметь любой из серии допустимых дочерних элементов, разделяемых символом |. Например, следующее DTD указывает, что элемент FILM может состоять из одного дочернего элемента STAR, или одного дочернего элемента NARRATOR, или одного дочернего элемента INSTRUCTOR:
<!DOCTYPE FILM [ <!ELEMENT FILM (STAR | NARRATOR | INSTRUCTOR)> <!ELEMENT STAR (#PCDATA)> <!ELEMENT NARRATOR (#PCDATA)> <!ELEMENT INSTRUCTOR (#PCDATA)> ] >
Следовательно, следующий элемент Документ будет валидным:
<FILM> <STAR>Robert Redford</STAR> </FILM>
как и элемент:
<FILM> <NARRATOR>Sir Gregory Parsloe</NARRATOR> </FILM>
а также элемент:
<FILM> <INSTRUCTOR>Galahad Threepwood</INSTRUCTOR> </FILM>
Следующий элемент Документ не будет валидным, поскольку вы можете включить только один из дочерних элементов:
<FILM> <!-- Неправильный элемент! --> <NARRATOR>Sir Gregory Parsloe</NARRATOR> <INSTRUCTOR>Galahad Threepwood</INSTRUCTOR> </FILM>
Вы можете изменить любую из этих форм модели содержимого, используя символы: знак вопроса (?), знак плюс (+) и звездочка (*), значения которых описаны в следующей таблице:
? | Ни одного или один из предшествующих элементов |
+ | Один или более из предшествующих элементов |
* | Ни одного или более из предшествующих элементов |
Например, следующее объявление означает, что вы можете включить один или более дочерних элементов NAME, и что дочерний элемент HEIGHT является не обязательным:
<!ELEMENT MOUNTAIN (NAME+, HEIGHT?, STATE)>
Таким образом, следующий элемент будет правильным:
<MOUNTAIN> <NAME>Pueblo Peak</NAME> <NAME>Taos Mountain</NAME> <STATE>New Mexico</STATE> </MOUNTAIN>
Другой пример: следующее объявление означает, что вы можете включить несколько или ни одного дочернего элемента STAR, либо один дочерний элемент NARRATOR, либо один дочерний элемент INSTRUCTOR:
<!ELEMENT FILM (STAR* | NARRATOR | INSTRUCTOR)>
Соответственно, каждый из следующих трех элементов будет корректным:
<FILM> <STAR>Tom Hanks</STAR> <STAR>Meg Ryan</STAR> </FILM> <FILM> <NARRATOR>Sir Gregory Parsloe</NARRATOR> </FILM> <FILM/>
Вы также можете воспользоваться символами ?, + или * для модификации всей модели содержимого, помещая символы непосредственно после закрывающих скобок. Например, следующее объявление дает вам возможность включить один или несколько дочерних элементов любого из этих трех типов в любом порядке:
<!ELEMENT FILM (STAR | NARRATOR | INSTRUCTOR)+>
Такое объявление делает корректными следующие элементы:
<FILM> <NARRATOR>Bertram Wooster</NARRATOR> <STAR>Sean Connery</STAR> <NARRATOR>Plug Basham</NARRATOR> </FILM> <FILM> <STAR>Sean Connery</STAR> <STAR>Meg Ryan</STAR> </FILM> <FILM> <INSTRUCTOR>Stinker Pike</INSTRUCTOR> </FILM>
Наконец, вы можете формировать более сложные модели содержимого путем вложения выборочной модели содержимого внутрь последовательной модели, либо последовательной модели в выборочную модель. Например, следующее DTD задает, что каждый элемент FILM должен иметь один дочерний элемент TITLE; за ним должен следовать один дочерний элемент CLASS; после него должен идти один дочерний элемент STAR, NARRATOR или INSTRUCTOR:
<!DOCTYPE FILM [ <!ELEMENT FILM (TITLE, CLASS, (STAR | NARRATOR | INSTRUCTOR) )> <!ELEMENT TITLE (#PCDATA)> <!ELEMENT CLASS (#PCDATA)> <!ELEMENT STAR (#PCDATA)> <!ELEMENT NARRATOR (#PCDATA)> <!ELEMENT INSTRUCTOR (#PCDATA)> ] >
В соответствии с этим DTD, следующий элемент Документ будет корректным:
<FILM> <TITLE>The Net</TITLE> <CLASS>fictional</CLASS> <STAR>Sandra Bullok</STAR> </FILM>
так же, как такой:
<FILM> <TITLE>How to Use XML</TITLE> <CLASS>instructional</CLASS> <INSTRUCTOR>Penny Donaldson</INSTRUCTOR> </FILM>
Добавление примитивов в документ
В следующем упражнении вы получите некоторый опыт работы с примитивами, добавив несколько общих примитивов в документ Inventory Valid.xml, созданный вами в лекции 5.
on_load_lecture()
« |
1
|
2
|
3
|
4
|
5
|
6
|
7
|
вопросы | »
для печати и PDA
Курсы | Учебные программы | Учебники | Новости | Форум | Помощь
Телефон: +7 (495) 253-9312, 253-9313, факс: +7 (495) 253-9310, email: info@intuit.ru © 2003-2007, INTUIT.ru::Интернет-Университет Информационных Технологий - дистанционное образование |
Добавьте примитивы в документ
- В вашем текстовом редакторе откройте документ 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.
Листинг 6.1. Inventory Valid Entity.xml (html, txt)
8. Если вы хотите проверить валидность вашего документа, воспользуйтесь сценарием проверки на валидность, приведенным в разделе "Проверка валидности XML-документа" в лекции 9.
Использование предварительно определенных примитивов
В 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.
Объявление нотаций
Нотация описывает определенный формат данных. Это делается путем указания адреса описания формата, адреса программы, которая может обрабатывать данные в этом формате, либо просто описание формата. Вы можете использовать нотацию, чтобы описать формат общего внешнего не разбираемого примитива (см. в предыдущем разделе), либо можете присвоить нотацию атрибуту, который имеет нумерованный тип 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 ИмяПримитива 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-страниц, которые могут получать доступ к примитивам и нотациям.
Объявление общего внешнего разбираемого примитива
Объявление для общего внешнего разбираемого примитива имеет следующую форму записи:
<!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"> ] >
Объявление общего внутреннего разбираемого примитива
Объявление общего внутреннего разбираемого примитива имеет следующую форму записи:
<!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>
Объявление общих примитивов
Примитив создается путем объявления его в DTD документа. Вы объявляете примитив с использованием разновидности объявления разметки, схожей с той, которая используется для объявления элементов и атрибутов. В последующих разделах вы узнаете, как объявлять каждый из типов общих примитивов.
Объявление параметрических примитивов
Форма объявления разметки параметрического примитива аналогична форме объявления, используемой для общих примитивов. В последующих разделах вы узнаете, как объявлять оба типа параметрических примитивов.
on_load_lecture()
« |
1
|
2
|
3
|
4
|
5
|
6
|
7
|
вопросы | »
для печати и PDA
Курсы | Учебные программы | Учебники | Новости | Форум | Помощь
Телефон: +7 (495) 253-9312, 253-9313, факс: +7 (495) 253-9310, email: info@intuit.ru © 2003-2007, INTUIT.ru::Интернет-Университет Информационных Технологий - дистанционное образование |
Объявление параметрического внешнего разбираемого примитива
Объявление для параметрического внешнего разбираемого примитива имеет следующую форму записи:
<!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 % ИмяПримитива ЗначениеПримитива>
Здесь ИмяПримитива есть имя примитива. Вы можете выбрать любое имя, соблюдая следующие правила:
имя должно начинаться с буквы или символа подчеркивания (_), вслед за которым могут идти или не идти буквы, цифры, точки (,), тире (–) или символы подчеркивания;примитив может иметь такое же имя, что и общий примитив в документе. (Параметрические и общие примитивы занимают различные пространства имен.) Имя примитива также может совпадать с именем элемента или атрибута;помните, что для всего текста разметки, в том числе и для имен примитивов, имеет значение регистр, в котором набраны символы. Так, примитив под именем 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'> ] >
Определения и классификация примитивов
Механизм примитивов в 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.
Вставка ссылок на примитив
Вставка содержимого (замещающий текст) примитива в документ осуществляется с помощью ссылок на примитив. Вы уже познакомились с несколькими примерами ссылок на примитив. Общий вид ссылки на общий примитив следующий:
&ИмяПримитива;
а на параметрический примитив:
%ИмяПримитива;
где ИмяПримитива есть имя, присваиваемое примитиву в объявлении. Исключением является общий внешний не разбираемый примитив, который вы не можете вставить с использованием ссылки. Единственный способ использования этого типа примитива заключается в присвоении его имени атрибуту, имеющему тип 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 – шестнадцатеричный числовой код символа | В содержимое элемента (см. "Вставка ссылок на символы") | ||
В значение атрибута (в качестве значения по умолчанию в объявление списка атрибутов, или в начальный тег элемента) (см. "Вставка ссылок на символы") | ||||
В значение в объявлении внутреннего примитива (см. "Вставка ссылок на символы") |
Вставка ссылок на символы
Вы можете воспользоваться ссылкой на символ, чтобы вставить символ, которого нет на вашей клавиатуре (например, 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 Organization 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">