Книга: Технология XSLT

Определение сущности

Определение сущности

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

Существует два способа определения сущности — внутреннее и внешнее.

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

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

<!ENTITY имя "значение">

Ссылка на сущность записывается как &имя; (амперсант, затем имя сущности, затем точка с запятой).

Пример

В документе

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE advert [
 <!ENTITY animal "слон">
]>
<advert>
 <product title="&animal;">
  Продается настоящий &animal;!
 </product>
</advert>

сущность animal имеет значение "слон". Ссылка на сущность используется дважды — в атрибуте title и в тексте элемента product. Этот документ эквивалентен документу

<?xml version="1.0" encoding="UTF-8"?>
<advert>
 <product title="слон">
  Продается настоящий слон!
 </product>
</advert>

Если в будущем фирма переквалифицируется, и будет продавать, скажем, жирафов, можно будет, не изменяя всего документа, заменить только значение сущности:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE advert [
 <!ENTITY animal "жираф">
]>
<advert>
 <product title="&animal;">
  Продается настоящий &animal;!
 </product>
</advert>

Спецификация XML определяет несколько встроенных сущностей, которые перечислены в табл 1.1.

Таблица 1.1. Встроенные сущности XML

Имя сущности Значение Описание
lt < знак "меньше"
gt > знак "больше"
amp & амперсант
apos ' апостроф или одинарные кавычки
quot " двойные кавычки

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

Пример

<?xml version="1.0" encoding="UTF-8"?>
<advert>
 <product title="слон">
  Продается серый слон весом &gt; 5 тонн!
  Компания &quot;слон &amp; Слон&quot;.
 </product>
</advert>

На самом же деле в элементе product заключен текст

Продается серый слон весом > 5 тонн!
Компания "Слон & Слон".

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

Символьная сущность (или, как ее еще называют, символьная ссылка) записывается в виде &#код; или &#xкод;, где код — десятеричный и шестнадцатеричный Unicode-код символа в первом и втором случае соответственно.

Пример

Фраза "Миру-мир!" может быть записана с использованием символьных сущностей следующим образом:

&#х41С;&#х438;&#х440;&#х443; - &#1084;&#1080;&#1088;!

Первое слово, "Миру" записано с использованием шестнадцатеричных unicode-кодов кириллицы, второе слово, "мир", записано с использованием десятичных кодов.

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

Определение внешней сущности имеет следующий синтаксис:

<!ENTITY имя SYSTEM "URI">

В этом определении имя точно так же, как и во внутренней сущности определяет имя сущности, в то время как URI определяет абсолютное или относительное местоположение файла.

Пример

Предположим, что мы создали файл animal.ent со следующим содержанием:

огромное серое животное

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

<!ENTITY animal SYSTEM "ent/animal.ent">

где ent/animal есть относительный путь до файла animal.ent. Если бы мы расположили файл на сервере, скажем, www.animalhost.com, сущность могла бы быть объявлена как

<!ENTITY animal SYSTEM "http://www.animalhost.com/animal.ent">

В документе ссылаться на объявленную внешнюю сущность мы будем точно так же, как ссылались бы на внутреннюю сущность:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE advert [
 <!ENTITY animal SYSTEM "ent/animal.ent">
]>
<advert>
 <product title="слон">
  Продается &animal; весом &gt; 5 тонн!
  Рождественские скидки!
 </product>
</advert>

В этом случае элемент product будет иметь текст

Продается огромное серое животное весом > 5 тонн!
Рождественские скидки!

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

Такой способ определения внешней сущности имеет следующий синтаксис:

<!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-языка вдруг произойдет смена регистра имен элементов xy и 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 — параметризованной сущности.

Оглавление книги


Генерация: 1.108. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз