Правильно построенные и действительные документы XML

Стандартом определены два уровня правильности документа XML:

· Правильно построенный (англ. well-formed). Правильно построенный документ соответствует всем общим правилам синтаксиса XML, применимым к любому XML-документу. И если, например, начальный тег не имеет соответствующего ему конечного тега, то это неправильно построенный документ XML. Документ, который неправильно построен, не может считаться документом XML; XML-процессор (парсер) не должен обрабатывать его обычным образом и обязан классифицировать ситуацию как фатальная ошибка.

· Действительный (англ. valid). Действительный документ дополнительно соответствует некоторым семантическим правилам. Это более строгая дополнительная проверка корректности документа на соответствие заранее определённым, но уже внешним правилам, в целях минимизации количества ошибок, например, структуры и состава данного, конкретного документа или семейства документов. Эти правила могут быть разработаны как самим пользователем, так и сторонними разработчиками, например, разработчиками словарей или стандартов обмена данными. Обычно такие правила хранятся в специальных файлах — схемах, где самым подробным образом описана структура документа, все допустимые названия элементов, атрибутов и многое другое. И если документ, например, содержит не определённое заранее в схемах название элемента, то XML-документ считается недействительным; проверяющий XML-процессор (валидатор) при проверке на соответствие правилам и схемам обязан (по выбору пользователя) сообщить об ошибке.

Синтаксис XML

В этом разделе рассматривается лишь правильное построение документов XML, то есть их синтаксис.

XML — это описанная в текстовом формате иерархическая структура, предназначенная для хранения любых данных. Визуально структура может быть представлена как дерево элементов. Элементы XML описываются тегами.

Рассмотрим пример простого кулинарного рецепта, размеченного с помощью XML:

<?xml version="1.0" encoding="UTF-8"?><recipe name="хлеб" preptime="5" cooktime="180"> <title>Простой хлеб</title> <ingredient amount="3" unit="стакан">Мука</ingredient> <ingredient amount="0.25" unit="грамм">Дрожжи</ingredient> <ingredient amount="1.5" unit="стакан">Тёплая вода</ingredient> <ingredient amount="1" unit="чайная ложка">Соль</ingredient> <instructions> <step>Смешать все ингредиенты и тщательно замесить.</step> <step>Закрыть тканью и оставить на один час в тёплом помещении.</step> <!-- <step>Почитать вчерашнюю газету.</step> - это сомнительный шаг... --> <step>Замесить ещё раз, положить на противень и поставить в духовку.</step> </instructions></recipe>

Объявление XML

Первая строка XML-документа называется объявление XML (англ. XML declaration) — это строка, указывающая версию XML. В версии 1.0 объявление XML может быть опущено, в версии 1.1 оно обязательно. Также здесь может быть указана кодировка символов и наличие внешних зависимостей.

<?xml version="1.0" encoding="UTF-8"?>

Спецификация требует, чтобы процессоры XML обязательно поддерживали Юникод-кодировки UTF-8 и UTF-16. Признаются допустимыми, поддерживаются и широко используются (но не обязательны) другие кодировки, основанные на стандарте ISO/IEC 8859, также допустимы другие кодировки, например, русские Windows-1251, KOI-8. Часто в тегах принципиально не используют не-латинские буквы, в этом случае UTF-8 является очень удобной кодировкой — объём, как правило, меньше, чем при UTF-16; декодирование может быть выполнено как для всего документа, так и для конкретных атрибутов и текстов; весь документ не содержит запрещённых символов при попытке разбора с неправильной кодировкой.

Корневой элемент

Важнейшее обязательное синтаксическое требование заключается в том, что документ имеет только один корневой элемент (англ. root element) (так же иногда называемый элемент документа (англ. document element)). Это означает, что текст или другие данные всего документа должны быть расположены между единственным начальным корневым тегом и соответствующим ему конечным тегом.

Следующий простейший пример — правильно построенный документ XML:

<book>Это книга: "Книжечка"</book>

Следующий пример не является корректным XML-документом, потому что имеет два корневых элемента:

<!-- ВНИМАНИЕ! Некорректный XML! --><thing>Сущность №1</thing><thing>Сущность №2</thing>

Комментарий

В любом месте дерева может быть размещен элемент-комментарий. XML-комментарии размещаются внутри специального тега, начинающегося с символов <!-- и заканчивающегося символами -->. Два знака дефис (--) внутри комментария присутствовать не могут.

<!-- Это комментарий. -->

Теги внутри комментария обрабатываться не должны.

Теги

Остальная часть этого XML-документа состоит из вложенных элементов, некоторые из которых имеют атрибуты и содержимое. Элемент обычно состоит из открывающего и закрывающего тегов, обрамляющих текст и другие элементы. Открывающий тег состоит из имени элемента в угловых скобках, например, <step>, а закрывающий тег состоит из того же имени в угловых скобках, но перед именем ещё добавляется косая черта, например, </step>. Имена элементов, как и имена атрибутов, не могут содержать пробелы, но могут быть на любом языке, поддерживаемом кодировкой XML-документа. Имя может начинаться с буквы, подчёркивания, двоеточия. Остальными символами имени могут быть те же символы, а также цифры, дефис, точка.

Содержимым элемента (англ. content) называется всё, что расположено между открывающим и закрывающим тегами, включая текст и другие (вложенные) элементы. Ниже приведён пример XML-элемента, который содержит открывающий тег, закрывающий тег и содержимое элемента:

<step>Замесить ещё раз, положить на противень и поставить в духовку.</step>

Кроме содержания у элемента могут быть атрибуты — пары имя-значение, добавляемые в открывающий тег после названия элемента. Значения атрибутов всегда заключаются в кавычки (одинарные или двойные), одно и то же имя атрибута не может встречаться дважды в одном элементе. Не рекомендуется использовать разные типы кавычек для значений атрибутов одного тега.

<ingredient amount="3" unit="стакан">Мука</ingredient>

В приведённом примере у элемента «ingredient» есть два атрибута: «amount», имеющий значение «3», и «unit», имеющий значение «стакан». С точки зрения XML-разметки, приведённые атрибуты не несут никакого смысла, а являются просто набором символов.

Кроме текста, элемент может содержать другие элементы:

<instructions> <step>Смешать все ингредиенты и тщательно замесить.</step> <step>Закрыть тканью и оставить на один час в тёплом помещении.</step> <step>Замесить ещё раз, положить на противень и поставить в духовку.</step></instructions>

В данном случае элемент «instructions» содержит три элемента «step».

XML не допускает перекрывающихся элементов. Например, приведённый ниже фрагмент некорректен, так как элементы «em» и «strong» перекрываются.

<!-- ВНИМАНИЕ! Некорректный XML! --><p>Обычный <em>акцентированный <strong>выделенный и акцентированный</em> выделенный</strong></p>

Для обозначения элемента без содержания, называемого пустым элементом, необходимо применять особую форму записи, состоящую из одного тега, в котором после имени элемента ставится косая черта. Если в DTD элемент не объявлен пустым, но в документе он не имеет содержания, для него допускается применять следующие (три) формы записи. Например:

<foo></foo><foo /><foo/>

Спецсимволы

В XML определены два метода записи специальных символов: ссылка на сущность и ссылка по номеру символа.

Сущностью (англ. entity) в XML называются именованные данные, обычно текстовые, в частности, спецсимволы. Ссылка на сущность (англ. entity references) указывается в том месте, где должна быть сущность и состоит из амперсанда (&), имени сущности и точки с запятой (;).

В XML есть несколько предопределённых сущностей, таких как lt (ссылаться на неё можно написав &lt;) для левой угловой скобки и amp (ссылка — &amp;) для амперсанда. Возможно также определять собственные сущности. Помимо записи с помощью сущностей отдельных символов, их можно использовать для записи часто встречающихся текстовых блоков.

Ниже приведён пример использования предопределённой сущности для избежания использования знака амперсанда в названии:

<company-name>AT&amp;T</company-name>

Полный список предопределённых сущностей состоит из &amp; (&), &lt; (<), &gt; (>), &apos; (') и &quot; (") — последние две полезны для записи разделителей внутри значений атрибутов. Определить свои сущности можно в DTD-документе.

Иногда бывает необходимо определить неразрывный пробел, который очень часто используется в HTML и обозначается как &nbsp;. В XML такой предопределённой сущности нет, его записывают &#160;, а использование &nbsp; вызывает ошибку. Отсутствие этой весьма распространённой сущности у множества программистов зачастую вызывает удивление и это создаёт некоторые трудности при миграции своих HTML-разработок в XML.

Ссылка по номеру символа (англ. numeric character reference) выглядит как ссылка на сущность, но вместо имени сущности указывается символ # и число (в десятичной или шестнадцатеричной записи), являющееся номером символа в кодовой таблице Юникод. Это обычно символы, которые невозможно закодировать напрямую, например, буква арабского алфавита в ASCII-кодированном документе. Амперсанд может быть представлен следующим образом:

<company-name>AT&#38;T</company-name>

Существуют и другие правила, касающиеся составления корректного XML-документа.

Сильные и слабые стороны

XML —позволяет стандартизировать вид файлов-данных, используемых компьютерными программами, в виде текста, понятного человеку; XML поддерживает Юникод; в формате XML могут быть описаны такие структуры данных как записи, списки и деревья; XML — это самодокументируемый формат, который описывает структуру и имена полей так же как и значения полей; XML имеет строго определённый синтаксис и требования к анализу. XML — формат, основанный на международных стандартах; Иерархическая структура XML подходит для описания практически любых типов документов, кроме аудио и видео мультимедийных потоков, растровых изображений, сетевых структур данных и двоичных данных; XML представляет собой простой текст, свободный от лицензирования и каких-либо ограничений; XML не зависит от платформы; XML не накладывает требований на порядок расположения атрибутов в элементе и вложенных элементов разных типов, что существенно облегчает выполнение требований обратной совместимости; В отличие от бинарных форматов, XML содержит метаданные об именах, типах и классах описываемых объектов, по которым приложение может обработать документ неизвестной структуры (например, для динамического построения интерфейсов); XML имеет реализации парсеров для всех современных языков программирования; Существует стандартный механизм преобразования XSLT, реализации которого встроены в браузеры, операционные системы, веб-серверы. XML поддерживается на низком аппаратном, микропрограммном и программном уровнях в современных аппаратных решениях.[5]

Недостатки. Синтаксис XML избыточен.[6] Размер XML-документа существенно больше бинарного представления тех же данных. В грубых оценках величину этого фактора принимают за 1 порядок (в 10 раз). Размер XML-документа существенно больше, чем документа в альтернативных текстовых форматах передачи данных (например JSON[2], YAML, Protocol Buffers) и особенно в форматах данных, оптимизированных для конкретного случая использования. XML содержит метаданные (об именах полей, классов, вложенности структур), и одновременно XML позиционируется как язык взаимодействия открытых систем. При передаче между системами большого количества объектов одного типа (одной структуры), передавать метаданные повторно нет смысла, хотя они содержатся в каждом экземпляре XML описания. В результате большой гибкости языка и отсутствия строгих ограничений, одна и та же структура может быть представлена множеством способов (различными разработчиками), например, значение может быть записано как атрибут тега или как тело тега и т. д. XML не содержит встроенной в язык поддержки типов данных. В нём нет строгой типизации, то есть понятий «целых чисел», «строк», «дат», «булевых значений» и т. д. Иерархическая модель данных, предлагаемая XML, ограничена по сравнению с реляционной моделью и объектно-ориентированными графами и сетевой моделью данных. Выражение неиерархических данных (например графов) требует дополнительных усилий Пространства имён XML сложно использовать и их сложно реализовывать в XML-парсерах. Существуют другие, обладающие сходными с XML возможностями, текстовые форматы данных, которые обладают более высоким удобством чтения человеком (YAML, JSON, SweetXML[11], XF[12]).

Наши рекомендации