Определение типа документа ( DTD ) — это файл спецификации, содержащий набор объявлений разметки , которые определяют тип документа для языка разметки семейства SGML ( GML , SGML , XML , HTML ). Файл спецификации DTD может использоваться для проверки документов.
DTD определяет допустимые строительные блоки XML-документа. Он определяет структуру документа со списком проверенных элементов и атрибутов. DTD может быть объявлен встроенным внутри XML-документа или как внешняя ссылка. [1]
Версия DTD, учитывающая пространство имен, разрабатывается как Часть 9 ISO DSDL . DTD сохраняются в приложениях, которым требуются специальные символы публикации, такие как XML и HTML Character Entity References , которые выводятся из более крупных наборов, определенных как часть стандарта ISO SGML . XML использует подмножество SGML DTD.
Начиная с 2009 года [обновлять], новые языки схем , поддерживающие пространство имен XML (такие как W3C XML Schema и ISO RELAX NG ), в значительной степени вытеснили DTD, став лучшим способом проверки структуры XML.
DTD связывается с документом XML или SGML посредством объявления типа документа (DOCTYPE). DOCTYPE появляется в синтаксическом фрагменте doctypedecl около начала документа XML. [2] Декларация устанавливает, что документ является экземпляром типа, определенного указанным DTD.
DOCTYPE делает два вида объявлений:
Декларации во внутреннем подмножестве являются частью DOCTYPE в самом документе. Декларации во внешнем подмножестве находятся в отдельном текстовом файле. На внешнее подмножество можно ссылаться через публичный идентификатор и/или системный идентификатор . Программам для чтения документов может не потребоваться читать внешнее подмножество.
Любой допустимый документ SGML или XML, который ссылается на внешнее подмножество в своем DTD или тело которого содержит ссылки на проанализированные внешние сущности, объявленные в его DTD (включая те, которые объявлены в его внутреннем подмножестве ), может быть проанализирован только частично, но не может быть полностью проверен проверкой парсерами SGML или XML в их автономном режиме (это означает, что эти проверяющие парсеры не пытаются извлечь эти внешние сущности, и их заменяющий текст недоступен).
Однако такие документы по-прежнему полностью поддаются анализу в неавтономном режиме валидирующих парсеров, который выдает ошибку, если не может найти эти внешние сущности с указанным публичным идентификатором (FPI) или системным идентификатором (URI) или они недоступны. (Нотации, объявленные в DTD, также ссылаются на внешние сущности, но эти неразобранные сущности не нужны для проверки документов в автономном режиме этих парсеров: проверка всех внешних сущностей, на которые ссылаются нотации, остается за приложением, использующим парсер SGML или XML). Невалидирующие парсеры могут в конечном итоге попытаться найти эти внешние сущности в неавтономном режиме (путем частичной интерпретации DTD только для разрешения их объявленных анализируемых сущностей), но не проверяют модель содержимого этих документов.
Следующий пример DOCTYPE содержит как публичные, так и системные идентификаторы:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
Все документы HTML 4.01 соответствуют одному из трех SGML DTD. Публичные идентификаторы этих DTD постоянны и следующие:
-//W3C//DTD HTML 4.01//EN
-//W3C//DTD HTML 4.01 Transitional//EN
-//W3C//DTD HTML 4.01 Frameset//EN
Системные идентификаторы этих DTD, если они присутствуют в DOCTYPE, являются ссылками URI . Системный идентификатор обычно указывает на определенный набор объявлений в разрешаемом месте. SGML позволяет сопоставлять публичные идентификаторы с системными идентификаторами в каталогах , которые опционально доступны для преобразователей URI, используемых программным обеспечением для анализа документов .
Этот DOCTYPE может появляться только после необязательной декларации XML и перед телом документа, если синтаксис документа соответствует XML. Это включает документы XHTML :
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!-- тело документа XHTML начинается здесь--> <html xmlns= "http://www.w3.org/1999/xhtml" > ... </html>
После внешнего подмножества может быть также предоставлено дополнительное внутреннее подмножество:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [ <!-- здесь можно встроить внутреннее подмножество -->]><!-- тело документа XHTML начинается здесь--> <html xmlns= "http://www.w3.org/1999/xhtml" > ... </html>
В качестве альтернативы может быть предоставлено только внутреннее подмножество:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html [ <!-- здесь можно встроить внутреннее подмножество -->]><!-- тело документа XHTML начинается здесь--> <html xmlns= "http://www.w3.org/1999/xhtml" > ... </html>
Наконец, определение типа документа может вообще не включать подмножества; в этом случае оно просто указывает, что документ имеет один элемент верхнего уровня (это неявное требование для всех допустимых документов XML и HTML, но не для фрагментов документов или для всех документов SGML, элементы верхнего уровня которых могут отличаться от подразумеваемого корневого элемента), и указывает имя типа корневого элемента:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html> <!-- тело документа XHTML начинается здесь--> <html xmlns= "http://www.w3.org/1999/xhtml" > ... </html>
DTD описывают структуру класса документов посредством объявлений элементов и списков атрибутов. Объявления элементов называют допустимый набор элементов в документе и определяют, могут ли и как могут содержаться объявленные элементы и последовательности символьных данных в каждом элементе. Объявления списков атрибутов называют допустимый набор атрибутов для каждого объявленного элемента, включая тип каждого значения атрибута, если это не явный набор допустимых значений.
Декларации разметки DTD определяют, какие типы элементов, списки атрибутов, сущности и нотации разрешены в структуре соответствующего класса XML-документов. [3]
Декларация типа элемента определяет элемент и его возможное содержимое. Действительный XML-документ содержит только элементы, определенные в DTD.
Различные ключевые слова и символы определяют содержимое элемента:
EMPTY
для указания того, что определенный элемент не допускает никакого содержимого, т. е. он не может иметь никаких дочерних элементов, даже текстовых (если есть пробелы, они игнорируются);ANY
для указания того, что определенный элемент допускает любое содержимое без ограничений, т. е. что он может иметь любое количество (включая отсутствие) и тип дочерних элементов (включая текстовые элементы);( #PCDATA )
: исторически означает проанализированные символьные данные , это означает, что в содержимом разрешен только один текстовый элемент (квантификатор не допускается);( #PCDATA | ''element name'' | ... )*
: ограниченный выбор (в исключительном списке, заключенном в скобки и разделенном |
символами вертикальной черты " " и завершающемся обязательным *
квантификатором " ") из двух или более дочерних элементов (включая только текстовые элементы или указанные именованные элементы) может использоваться в любом порядке и количестве вхождений в контент.,
запятой " ") из одной или нескольких частиц контента : все частицы контента должны появляться последовательно как прямые дочерние элементы в контенте определенного элемента, в указанной позиции и относительном порядке;|
вертикальной черты " ") из двух или более частиц контента : только одна из этих частиц контента может появляться в содержимом определенного элемента в одной и той же позиции.+
для указания того, что элемент должен встречаться один или несколько раз — фактическое содержание каждого появления может быть разным;*
для указания того, что допускается любое количество (ноль или более) вхождений — элемент является необязательным, и эффективное содержание каждого вхождения может быть разным;?
для указания того, что не должно быть более одного вхождения — элемент является необязательным;Например:
<!ELEMENT html ( заголовок , тело ) > <!ELEMENT p ( #PCDATA | p | ul | dl | таблица | h1 | h2 | h3 )* >
Декларации типов элементов игнорируются непроверяющими парсерами SGML и XML (в таких случаях любые элементы принимаются в любом порядке и в любом количестве вхождений в анализируемом документе), но эти декларации все равно проверяются на предмет формы и допустимости.
Список атрибутов определяет для данного типа элемента список всех возможных атрибутов, связанных с этим типом. Для каждого возможного атрибута он содержит:
Например:
<!ATTLIST img src CDATA #ОБЯЗАТЕЛЬНЫЙ id ID #ПРЕДПОЛАГАЕТСЯ sort CDATA # ИСПРАВЛЕНО "true" print ( да | нет ) "yes" >
Вот некоторые типы атрибутов, поддерживаемые как SGML, так и XML:
CDATA
ID
xml:id
с этим типом, без необходимости какого-либо объявления в DTD, поэтому ограничение уникальности также применяется к этим определенным идентификаторам, когда они указаны в любом месте XML-документа.IDREF
илиIDREFS
ID
в DTD (или уникальный элемент, определенный в XML-документе с псевдоатрибутом " xml:id
"), и эффективное значение которого является тем же идентификатором;NMTOKEN
илиNMTOKENS
ENTITY
илиENTITIES
(value1|...)
|
вертикальной черты " ") текстовых значений, где каждое значение в перечислении может быть указано в '
одинарных '
или "
двойных "
кавычках, если это не простой токен имени;NOTATION (notation1|...)
|
вертикальной черты " ") имен нотаций, где каждое имя нотации в перечислении должно быть также объявлено в объявлении типа документа; этот тип не поддерживается в анализаторах HTML, но действителен в SGML и XML 1.0 или 1.1 (включая XHTML и SVG).Значение по умолчанию может определять, должен ли атрибут присутствовать ( #REQUIRED
) или нет ( #IMPLIED
), имеет ли он фиксированное значение ( #FIXED
), или какое значение следует использовать в качестве значения по умолчанию («…») в случае, если данный атрибут пропущен в теге XML.
Объявления списка атрибутов игнорируются непроверяющими парсерами SGML и XML (в этих случаях любой атрибут принимается во всех элементах анализируемого документа), но эти объявления все равно проверяются на правильность формирования и допустимость.
Сущность похожа на макрос . Объявление сущности присваивает ей значение, которое сохраняется во всем документе. Обычно используется для того, чтобы имя было более узнаваемым, чем числовая ссылка на незнакомый символ. [5] Сущности помогают улучшить читаемость XML-текста. В общем, существует два типа: внутренние и внешние.
Пример внутренних деклараций сущностей (здесь во внутреннем подмножестве DTD документа SGML):
<!DOCTYPE sgml [ <!ELEMENT sgml ANY > <!ENTITY % std "standard SGML" > <!ENTITY % signature " — &author;." > <!ENTITY % question "Почему я не могу опубликовать свои книги напрямую в %std;?" > <!ENTITY % author "William Shakespeare" > ]>
<sgml> &вопрос;&подпись; </sgml>
Внутренние сущности могут быть определены в любом порядке, пока они не упоминаются и не анализируются в DTD или в теле документа в порядке их анализа: допустимо включать ссылку на еще неопределенную сущность в содержимое анализируемой сущности, но недопустимо включать где-либо еще ссылку на любую именованную сущность до того, как эта сущность будет полностью определена, включая все другие внутренние сущности, на которые есть ссылки в ее определенном содержимом (это также предотвращает циклические или рекурсивные определения внутренних сущностей). Этот документ анализируется так, как если бы он был:
<!DOCTYPE sgml [ <!ELEMENT sgml ANY > <!ENTITY % std "standard SGML" > <!ENTITY % signature " — &author;." > <!ENTITY % question "Почему я не могу опубликовать свои книги напрямую в стандартном SGML?" > <!ENTITY % author "William Shakespeare" > ]>
<sgml> Почему я не могу публиковать свои книги напрямую в стандартном SGML? — Уильям Шекспир. </sgml>
Ссылка на внутреннюю сущность "author" не заменяется в тексте замены внутренней сущности "signature". Вместо этого она заменяется только тогда, когда ссылка на сущность "signature" анализируется в содержимом элемента "sgml", но только проверяющими парсерами (непроверяющие парсеры не заменяют ссылки на сущности, встречающиеся в содержимом элемента или в значениях атрибутов в теле документа).
Это возможно, поскольку текст замены, указанный во внутренних определениях сущностей, позволяет различать ссылки на сущности параметров (которые вводятся символом "%" и замена которых применяется к проанализированному содержимому DTD) и общие ссылки на сущности (которые вводятся символом "&" и замена которых откладывается до тех пор, пока они не будут эффективно проанализированы и проверены). Символ "%" для введения ссылок на сущности параметров в DTD теряет свою особую роль за пределами DTD и становится литеральным символом.
Однако ссылки на предопределенные символьные сущности подставляются везде, где они встречаются, без необходимости использования проверяющего синтаксического анализатора (они вводятся только символом «&»).
Нотации используются в SGML или XML. Они предоставляют полную ссылку на неанализируемые внешние сущности, интерпретация которых оставлена на усмотрение приложения (которое интерпретирует их напрямую или извлекает внешнюю сущность самостоятельно), присваивая им простое имя, которое можно использовать в тексте документа. Например, нотации могут использоваться для ссылки на не-XML-данные в документе XML 1.1. Например, для аннотирования изображений SVG с целью их привязки к определенному рендереру:
<!НОТАЦИЯ тип-изображение-svg СИСТЕМА "image/svg" >
Это объявляет ТЕКСТ внешних изображений с этим типом и связывает его с именем нотации "type-image-svg". Однако имена нотаций обычно следуют соглашению об именовании, которое является специфическим для приложения, генерирующего или использующего нотацию: нотации интерпретируются как дополнительные метаданные, эффективное содержимое которых является внешней сущностью и либо PUBLIC FPI, зарегистрированным в каталогах, используемых анализаторами XML или SGML, либо SYSTEM URI, интерпретация которого зависит от приложения (здесь тип MIME, интерпретируемый как относительный URI, но это может быть абсолютный URI для конкретного рендерера или URN, указывающий идентификатор объекта, специфичный для ОС, такой как UUID).
Объявленное имя нотации должно быть уникальным в пределах всех объявлений типов документов, т. е. как во внешнем подмножестве, так и во внутреннем подмножестве, по крайней мере для соответствия XML. [6] [7]
Нотации могут быть связаны с неразобранными внешними сущностями, включенными в тело документа SGML или XML. Параметр PUBLIC
or SYSTEM
этих внешних сущностей указывает FPI и/или URI, где находятся неразобранными данные внешней сущности, а дополнительный NDATA
параметр этих определенных сущностей указывает дополнительную нотацию (т. е. фактически тип MIME здесь). Например:
<!DOCTYPE sgml [ <!ELEMENT sgml ( img )* > <!ЭЛЕМЕНТ img ПУСТО > <!ATTLIST img data СУЩНОСТЬ #ПРЕДПОЛАГАЕТСЯ > <!ENTITY example1SVG SYSTEM "example1.svg" NDATA example1SVG-rdf > <!NOTATION example1SVG-rdf SYSTEM "example1.svg.rdf" > ]>
<sgml> <img data= "example1SVG" /> </sgml>
В тексте документа SGML эти внешние сущности, на которые есть ссылки (чье имя указано между «&» и «;»), не заменяются, как обычные именованные сущности (определенные со значением CDATA), а остаются как отдельные неанализируемые токены, которые могут использоваться либо как значение атрибута элемента (как выше), либо в содержимом элемента, при условии, что либо DTD допускает такие внешние сущности в объявленном типе содержимого элементов или в объявленном типе атрибутов (здесь тип ENTITY
для data
атрибута), либо анализатор SGML не проверяет содержимое.
Нотации также могут быть напрямую связаны с элементами как дополнительные метаданные, без связывания их с другой внешней сущностью, путем указания их имен в качестве возможных значений некоторых дополнительных атрибутов (также объявленных в DTD в объявлении элемента). Например:<!ATTLIST ...>
<!DOCTYPE sgml [ <!ELEMENT sgml ( img )* > <!-- необязательное значение атрибута "type" может быть установлено только для этой нотации. --> <!ATTLIST sgml type NOTATION ( type-vendor-specific ) #IMPLIED > <!ELEMENT img ANY > <!-- необязательным содержимым могут быть только анализируемые данные SGML или XML --> <!-- Необязательное значение атрибута "title" должно анализироваться как текст. Необязательное значение атрибута "data" устанавливается на неанализируемую внешнюю сущность. Необязательное значение атрибута "type" может быть только одной из двух нотаций. --> <!ATTLIST img title CDATA #IMPLIED data ENTITY #IMPLIED type NOTATION ( type-image-svg | type-image-gif ) #IMPLIED > <!-- Нотации ссылаются на внешние сущности и могут быть установлены в атрибутах "type" выше, или на них должны ссылаться любые определенные внешние сущности, которые не могут быть проанализированы. --> <!NOTATION type-image-svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > <!NOTATION type-image-gif PUBLIC "image/gif" > <!NOTATION type-vendor-specific PUBLIC "application/VND.specific+sgml" > <!ENTITY example1SVGTitle "Заголовок example1.svg" > <!-- проанализированная внутренняя сущность --> <!ENTITY example1SVG SYSTEM "example1.svg" > <!-- проанализированная внешняя сущность --> <!ENTITY example1GIFTitle "Заголовок example1.gif" > <!-- проанализированная внутренняя сущность --> <!ENTITY example1GIF SYSTEM "example1.gif" NDATA type-image-gif > <!-- непроанализированная внешняя сущность --> ]>
<sgml type= "type-vendor-specific" > <!-- изображение SVG можно проанализировать как допустимый текст SGML или XML --> <img title= "&example1SVGTitle;" type= "type-image-svg" > &example1SVG; </img> <!-- на него также можно ссылаться как на неанализируемую внешнюю сущность --> <img title= "&example1SVGTitle;" data= "example1SVG" /> <!-- изображение GIF не поддается анализу и на него можно ссылаться только как на внешнюю сущность --> <img title= "&example1GIFTitle;" data= "example1GIF" /> </sgml>
В приведенном выше примере показана нотация с именем "type-image-svg", которая ссылается на стандартный публичный FPI и системный идентификатор (стандартный URI) документа SVG 1.1, вместо указания просто системного идентификатора, как в первом примере (который был относительным URI, интерпретируемым локально как тип MIME). Эта аннотация напрямую ссылается на неанализируемый атрибут "type" элемента "img", но его содержимое не извлекается. Она также объявляет другую нотацию для специфичного для поставщика приложения, чтобы аннотировать корневой элемент "sgml" в документе. В обоих случаях объявленная нотация с именем используется напрямую в объявленном атрибуте "type", содержимое которого указано в DTD с типом атрибута "NOTATION" (этот атрибут "type" объявлен для элемента "sgml", а также для элемента "img").
Однако атрибут «title» элемента «img» указывает внутреннюю сущность «example1SVGTitle», чье объявление не определяет аннотацию, поэтому оно анализируется проверяющими парсерами, и текстом замены сущности является «Title of example1.svg».
Содержимое элемента "img" ссылается на другую внешнюю сущность "example1SVG", чье объявление также не определяет нотацию, поэтому оно также анализируется проверяющими парсерами, а текст замены сущности находится по его определенному идентификатору SYSTEM "example1.svg" (также интерпретируемому как относительный URI). Эффективным содержимым для элемента "img" будет содержимое этого второго внешнего ресурса. Разница с изображением GIF заключается в том, что изображение SVG анализируется в документе SGML, согласно объявлениям в DTD, где изображение GIF просто ссылается как на непрозрачный внешний объект (который не поддается анализу с помощью SGML) через его атрибут "data" (тип значения которого является непрозрачным ENTITY).
В значении атрибутов ENTITY может быть указано только одно имя нотации (в SGML, XML 1.0 или XML 1.1 нет поддержки для нескольких имен нотаций в одном и том же объявленном внешнем ENTITY, поэтому необходимы отдельные атрибуты). Однако в атрибутах, объявленных с типом ENTITIES, могут быть указаны несколько внешних сущностей (в списке имен, разделенных пробелами), и где каждая именованная внешняя сущность также объявлена со своей собственной нотацией).
Нотации также полностью непрозрачны для парсеров XML и SGML, поэтому они не различаются по типу внешней сущности, на которую они могут ссылаться (для этих парсеров у них просто есть уникальное имя, связанное с публичным идентификатором (FPI) и/или системным идентификатором (URI)).
Некоторые приложения (но не сами парсеры XML или SGML) также позволяют ссылаться на нотации косвенно, называя их в "URN:''name''"
значении стандартного атрибута CDATA, везде, где может быть указан URI. Однако это поведение зависит от приложения и требует, чтобы приложение поддерживало каталог известных URN для их преобразования в нотации, которые были проанализированы в стандартном парсере SGML или XML. Такое использование позволяет определять нотации только в DTD, хранящемся как внешняя сущность, и ссылаться только как на внешнее подмножество документов, и позволяет этим документам оставаться совместимыми с проверкой парсеров XML или SGML, которые не имеют прямой поддержки нотаций.
Нотации не используются в HTML или в базовых профилях для XHTML и SVG, потому что:
Даже при проверке парсеров SGML или XML 1.0 или XML 1.1 внешние сущности, на которые ссылаются FPI и/или URI в объявленных нотациях, не извлекаются автоматически самими парсерами. Вместо этого эти парсеры просто предоставляют приложению проанализированные FPI и/или URI, связанные с нотациями, найденными в проанализированном документе SGML или XML, и с возможностью для словаря, содержащего все имена нотаций, объявленные в DTD; эти проверяющие парсеры также проверяют уникальность объявлений имен нотаций и сообщают об ошибке проверки, если некоторые имена нотаций используются где-либо в DTD или в теле документа, но не объявлены:
Синтаксис XML DTD является одним из нескольких языков схем XML . Однако многие языки схем не полностью заменяют XML DTD. В частности, XML DTD позволяет определять сущности и нотации, которые не имеют прямых эквивалентов в XML без DTD (поскольку внутренние сущности и анализируемые внешние сущности не являются частью языков схем XML, и потому что другие неанализируемые внешние сущности и нотации не имеют простых эквивалентных отображений в большинстве языков схем XML).
Большинство языков схем XML являются лишь заменой объявлений элементов и объявлений списков атрибутов, таким образом, что становится возможным анализировать XML-документы с помощью невалидирующих XML-анализаторов (если единственной целью внешнего подмножества DTD было определение схемы). Кроме того, документы для этих языков схем XML должны анализироваться отдельно, поэтому проверка схемы XML-документов в чистом автономном режиме на самом деле невозможна с этими языками: объявление типа документа остается необходимым, по крайней мере, для идентификации (с помощью XML-каталога ) схемы, используемой в анализируемом XML-документе, и это проверяется на другом языке.
Распространенное заблуждение заключается в том, что непроверяющий синтаксический анализатор XML не должен читать объявления типов документов, хотя на самом деле объявления типов документов все равно должны сканироваться на предмет правильности синтаксиса, а также допустимости объявлений, и синтаксический анализатор все равно должен анализировать все объявления сущностей во внутреннем подмножестве и подставлять заменяющие тексты внутренних сущностей, встречающиеся в любом месте объявления типа документа или в теле документа.
Однако непроверяющий синтаксический анализатор может решить не читать анализируемые внешние сущности (включая внешнее подмножество ) и не обязан соблюдать ограничения модели содержимого, определенные в объявлениях элементов и в объявлениях списков атрибутов.
Если XML-документ зависит от анализируемых внешних сущностей (включая указанное внешнее подмножество или анализируемых внешних сущностей, объявленных во внутреннем подмножестве ), он должен утверждать standalone="no"
в своей XML-декларации. Проверяющий DTD может быть идентифицирован с помощью XML-каталогов для извлечения его указанного внешнего подмножества .
В приведенном ниже примере XML-документ объявлен с помощью , standalone="no"
поскольку в его объявлении типа документа имеется внешнее подмножество:
<?xml версия="1.0" кодировка="UTF-8" автономный="нет"?> <!DOCTYPE people_list SYSTEM "example.dtd"> <people_list />
Если декларация типа документа XML включает любой идентификатор SYSTEM для внешнего подмножества, его нельзя безопасно обрабатывать как автономный: следует извлечь URI, в противном случае могут быть неизвестные именованные символьные сущности, определение которых может потребоваться для правильного разбора эффективного синтаксиса XML во внутреннем подмножестве или в теле документа (разбор синтаксиса XML обычно выполняется после подстановки всех именованных сущностей, за исключением пяти сущностей, которые предопределены в XML и которые неявно подставляются после разбора документа XML на лексические токены). Если он просто включает любой идентификатор PUBLIC, его можно обрабатывать как автономный, если процессор XML знает этот идентификатор PUBLIC в своем локальном каталоге, откуда он может извлечь связанную сущность DTD.
Пример очень простого внешнего XML DTD для описания схемы списка лиц может включать:
<!ELEMENT people_list ( person )* > <!ELEMENT person ( name , birthdate ?, gender ?, socialsecuritynumber ?) > <!ELEMENT name ( #PCDATA ) > <!ELEMENT birthdate ( #PCDATA ) > <!ELEMENT gender ( #PCDATA ) > <!ELEMENT socialsecuritynumber ( #PCDATA ) >
Разбираем это построчно:
people_list
является допустимым именем элемента, и экземпляр такого элемента содержит любое количество person
элементов. *
Обозначает, что внутри элемента может быть 0 или более person
элементов people_list
.person
является допустимым именем элемента, и экземпляр такого элемента содержит один элемент с именем name
, за которым следует один с именем birthdate
(необязательно), затем gender
(также необязательно) и socialsecuritynumber
(также необязательно). ?
Указывает, что элемент является необязательным. Ссылка на name
имя элемента не имеет ?
, поэтому person
элемент должен содержать name
элемент.name
является допустимым именем элемента, и экземпляр такого элемента содержит «проанализированные символьные данные» (#PCDATA).birthdate
является допустимым именем элемента, и экземпляр такого элемента содержит проанализированные символьные данные.gender
является допустимым именем элемента, и экземпляр такого элемента содержит проанализированные символьные данные.socialsecuritynumber
является допустимым именем элемента, и экземпляр такого элемента содержит проанализированные символьные данные.Ниже приведен пример XML-файла, который использует и соответствует этому DTD. DTD упоминается здесь как внешнее подмножество через спецификатор SYSTEM и URI. Предполагается, что мы можем идентифицировать DTD с помощью относительной ссылки URI "example.dtd"; "people_list" после "!DOCTYPE" говорит нам, что корневые теги или первый элемент, определенный в DTD, называется "people_list":
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE people_list SYSTEM "example.dtd"> <people_list> <person> <name> Фред Блоггс </name> <birthdate> 2008-11-27 </birthdate> <gender> Мужской </gender> </person> </people_list>
Можно отобразить это в браузере с поддержкой XML (например, Internet Explorer или Mozilla Firefox ), вставив и сохранив компонент DTD выше в текстовый файл с именем example.dtd , а файл XML — в текстовый файл с другим именем, и открыв файл XML в браузере. Оба файла должны быть сохранены в одном каталоге. Однако многие браузеры не проверяют, соответствует ли документ XML правилам DTD; им требуется только проверить синтаксическую правильность DTD. По соображениям безопасности они также могут не читать внешний DTD.
Тот же DTD можно также встроить непосредственно в сам XML-документ как внутреннее подмножество, заключив его в [квадратные скобки] в объявлении типа документа. В этом случае документ больше не зависит от внешних сущностей и может обрабатываться в автономном режиме:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!DOCTYPE people_list [ <!ELEMENT people_list (person*)> <!ELEMENT person (имя, дата рождения?, пол?, номер социального страхования?)> <!ELEMENT имя (#PCDATA)> <!ELEMENT дата рождения (#PCDATA)> <!ELEMENT пол (#PCDATA)> <!ELEMENT номер социального страхования (#PCDATA)> ]><people_list> <person> <name> Фред Блоггс </name> <birthdate> 2008-11-27 </birthdate> <gender> Мужской </gender> </person> </people_list>
Доступны альтернативы DTD (для указания схем):
XML DTD может использоваться для создания атаки типа «отказ в обслуживании» (DoS) путем определения вложенных сущностей, которые расширяются экспоненциально, или путем отправки XML-анализатора на внешний ресурс, который никогда не возвращается. [10]
По этой причине .NET Framework предоставляет свойство, позволяющее запрещать или пропускать анализ DTD, [10] а последние версии приложений Microsoft Office (Microsoft Office 2010 и выше) отказываются открывать XML-файлы, содержащие декларации DTD.