Такой способ определения внешней сущности имеет следующий синтаксис:
<!ENTITY имя PUBLIC "идентификатор" "URL">
Например, сущность animal мы можем переопределить как
<!ENTITY animal PUBLIC "-//ZOO//Elephant//Description"
"http://www.animalhost.com/animal.ent">
Специальный процессор зоологических XML-файлов, встретив публичный идентификатор -//ZOO//Elephant//Description поймет, что речь идет о слоне, и не станет загружать файл animal.ent с удаленного сервера, вставив собственное описание слона.
Подводя итог, можно выделить следующие случаи, когда следует использовать сущности:
□ замена часто повторяющихся частей документа;
□ разбивка одного XML-документа на отдельные модули;
□ замена некоторых символов, которые иначе были бы восприняты, как разметка;
□ использование символов с соответствующими кодами Unicode.
Синтаксис использования сущностей в тексте документа довольно прост. Символьная сущность определяется продукцией CharRef следующим образом:
[66] CharRef ::= '&#' [0-9]+ ';' | "&#x' [0-9a-fA-F]+ ';'
CharRef — это либо десятичная, либо шестнадцатеричная символьная сущность. В первом случае вместо имени сущности стоит набор, цифр от 0 до 9, во втором — к этому набору добавляются буквы a, b, c, d, e, f в любом регистре символов. Ведущие нули не имеют никакого значения, &#х0020; точно так же, как и &#х20; соответствует пробельному символу.
Обычной сущности, объявленной внутри или вне документа, соответствует продукция EntityRef:
[68] EntityRef ::= '&' Name
Символьная и обычная сущности объединяются в продукцию Reference:
[67] Reference ::= EntityRef | CharRef
Здесь следует сделать небольшое отступление и сказать о том, что конструкции вида &имя; или &#xкод;, о которых мы говорили как о сущностях, на самом деле являются не сущностями, а ссылками на сущности. &#xкод; — это ссылка на символьную, а &имя; — на обычную сущность. Сама сущность — это именованный объект, к которому обрабатывающая программа должна обращаться при обработке ссылки с соответствующим именем. Однако, поскольку связь между сущностью и ссылкой на нее однозначна (одно не существует без другого), сами ссылки очень часто называют сущностями. Название продукции Reference переводится с английского как "ссылка", но пониматься в данном контексте может, в том числе, и как сущность.
Определение обычной сущности соответствует следующей продукции:
[71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
Name, как обычно, определяет имя, a EntityDef, соответственно, значение сущности. Это значение может быть задано как внутри документа (первый вариант выбора, EntityValue), так и вне его (второй вариант, ExternalID NDataDecl?).
[73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
EntityValue — это всего лишь символьное значение, взятое в кавычки.
Второй вариант синтаксиса EntityDef соответствует определению внешней сущности, то есть сущности, определение которой не содержится в самом документе.
Внешние сущности могут быть двух типов:
□ разбираемые внешние сущности (англ. parsed entity) — данные, которые воспринимаются и обрабатываются как XML;
□ неразбираемые внешние сущности (англ. unparsed entity) — данные не-XML типа (например, изображения или бинарные файлы, которые необходимо использовать в данном документе).
Неразбираемые сущности определяются наличием нетерминала NDataDecl в определении.
[76] NdataDecl ::= S 'NDATA' S Name
Мы до сих пор не упомянули еще один важный случай сущности — параметризованные сущности или сущности-параметры. Сущности этого типа используются в DTD для более гибкого описания логической структуры документа.
Синтаксически сущности-параметры очень похожи на обычные сущности. При объявлении и использовании сущности-параметра ее имени должен предшествовать символ '%'. Отличием сущностей-параметров является то, что они определяются и используются только внутри DTD.
В качестве примера объявим параметризованную сущность coords, которую впоследствии будем использовать в определениях элементов:
<!ENTITY % coords "x, y, z">
Используя объявленную сущность-параметр, элемент sphere, состоящий из элементов x, y, z (координаты сферы) и R (радиус), можно определить следующим образом:
<!ELEMENT sphere (%coords;, R)>
Такое определение равносильно определению <!ELEMENT sphere (x, y, z, r) >, но при этом оно является гораздо более гибким — если в новой версии создаваемого XML-языка вдруг произойдет смена регистра имен элементов x, y и z на X, Y и Z, декларацию типа документа изменять не придется.
Сущности-параметры широко используются в спецификациях Консорциума W3. Язык XSLT тоже имеет свою декларацию типа документа, но ее невозможно будет понять, не понимая механизма сущностей-параметров.
Синтаксис использования сущности-параметра (вернее, ссылки на нее) соответствует продукции PEReference, которая практически совпадает с продукцией EntityRef:
[69] PEReference ::= '%' Name ';'
Определение сущности-параметра также очень схоже с определением обычной сущности:
[72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
[74] PEDef ::= EntityValue | ExternalID
Продукция EntityDecl, соответствующая определению сущности, как обычной, так и сущности-параметра, имеет следующий вид:
[70] EntityDecl ::= GEDecl | PEDecl
Напомним, что GEDecl соответствует объявлению обычной, a PEDecl — параметризованной сущности.
Определение нотации
С точки зрения физической модели, XML-документы являются не более чем текстом. Содержимое документов и их разметка имеет исключительно текстовый вид. Вместе с тем, во многих случаях документы должны включать данные других форматов, например, графические изображения или двоичные файлы. Несовместимость физической реализации XML и внешних данных такого типа не позволяет включать их в документ посредством обычных сущностей — для этих целей используются неразбираемые сущности и нотации.
Нотация — это ни что иное, как определение формата неразбираемой сущности. Нотация дает формату имя и предоставляет некоторую информацию о приложении, которое следует использовать для обработки этого формата.
Предположим, что мы используем графические изображения в формате GIF, для просмотра которых используется приложение gif-viewer.exe. Определение нотации будет иметь следующий вид: