LEARN X · ЗА 10 МИН

XML

XML за 10 минут: структура документа, элементы, атрибуты, CDATA, сущности, пространства имён, well-formed и практический пример конфига.

XML (eXtensible Markup Language) — текстовый формат для хранения и передачи структурированных данных в виде дерева помеченных элементов. Он не описывает внешний вид (как HTML), а описывает смысл и структуру данных. Этот экспресс-тур — вся азбука XML на одной странице через плотно закомментированный код.

Что такое XML и общая структура

Документ XML — это дерево элементов с единственным корнем. Часто начинается с декларации (пролога).

<?xml version="1.0" encoding="UTF-8"?>
<!-- Это декларация XML: версия и кодировка. Необязательна, но рекомендуется. -->
<!-- Так выглядит комментарий: его текст игнорируется парсером. -->

<!-- Ниже корневой элемент: ровно один на весь документ -->
<library>
  <book>
    <title>Война и мир</title>
    <author>Толстой</author>
  </book>
</library>
<!-- Документ = пролог + ровно один корневой элемент (дерево). -->

Элементы и теги

Элемент состоит из открывающего тега, содержимого и закрывающего тега. Бывают пустые элементы.

<!-- Открывающий тег <title> ... закрывающий тег </title> -->
<title>Привет, XML</title>

<!-- Вложенность: элементы образуют дерево, теги не должны пересекаться -->
<person>
  <name>Анна</name>
  <city>Москва</city>
</person>

<!-- Пустой элемент можно записать двумя способами: -->
<line></line>   <!-- открыли и сразу закрыли -->
<line/>          <!-- самозакрывающийся тег (то же самое) -->

<!-- Имена тегов чувствительны к регистру: <Name> и <name> РАЗНЫЕ -->

Атрибуты

Атрибуты задаются внутри открывающего тега в формате name="value". Значение всегда в кавычках.

<!-- Атрибуты id и lang у элемента book -->
<book id="42" lang="ru">
  <title>XML за 10 минут</title>
</book>

<!-- Можно одинарные или двойные кавычки, но кавычки ОБЯЗАТЕЛЬНЫ -->
<item name='чай' qty="3"/>

<!-- Один атрибут не может повторяться в одном теге: -->
<!-- <book id="1" id="2"/>  <- ОШИБКА, дубль атрибута -->

Корневой элемент и иерархия

В документе ровно один корневой (родительский для всех) элемент. Остальные вложены в него.

<!-- <catalog> — корень. Внутри потомки, у потомков свои потомки. -->
<catalog>
  <product>                  <!-- ребёнок корня -->
    <name>Клавиатура</name>  <!-- внук корня -->
    <price>2990</price>
  </product>
  <product>
    <name>Мышь</name>
    <price>1490</price>
  </product>
</catalog>
<!-- ДВА корня на верхнем уровне запрещены — только один. -->

Текст и CDATA

Если внутри текста нужны символы вроде &lt; или &amp; без экранирования, оборачивают в секцию CDATA.

<!-- Обычный текстовый узел внутри элемента -->
<message>Просто текст</message>

<!-- CDATA: всё внутри воспринимается буквально, как есть -->
<code>
  <![CDATA[
    if (a < b && b > 0) { ok(); }
  ]]>
</code>
<!-- Внутри <![CDATA[ ... ]]> символы < и & НЕ нужно экранировать. -->
<!-- Единственное, что нельзя писать внутри CDATA — последовательность ]]> -->

Сущности (entities)

Спецсимволы заменяются именованными сущностями. Сущность начинается с &amp; и заканчивается точкой с запятой.

<!-- 5 встроенных сущностей XML: -->
<!-- &amp;lt;   даёт символ  <  (меньше)        -->
<!-- &amp;gt;   даёт символ  >  (больше)        -->
<!-- &amp;amp;  даёт символ  &  (амперсанд)     -->
<!-- &amp;quot; даёт символ  "  (кавычка)       -->
<!-- &amp;apos; даёт символ  '  (апостроф)      -->

<formula>1 &amp;lt; 2 &amp;amp;&amp;amp; 3 &amp;gt; 2</formula>
<!-- В тексте выше парсер прочитает:  1 < 2 && 3 > 2 -->

<!-- Числовая ссылка: &amp;#169; — знак ©, &amp;#x2764; — ❤ (hex) -->

Пространства имён (namespaces)

Чтобы избежать конфликта одинаковых имён из разных словарей, используют префиксы и xmlns.

<!-- Объявляем namespace с префиксом h, привязанным к URI -->
<root xmlns:h="http://example.com/html"
      xmlns:f="http://example.com/furniture">

  <h:table>            <!-- table из словаря HTML -->
    <h:tr><h:td>Ячейка</h:td></h:tr>
  </h:table>

  <f:table>            <!-- table из мебельного словаря — не путается -->
    <f:width>120</f:width>
  </f:table>
</root>

<!-- xmlns="..." без префикса задаёт namespace по умолчанию для поддерева -->

Правила правильной формы (well-formed)

Документ считается well-formed, если соблюдены базовые синтаксические правила. Иначе парсер откажется его читать.

<!-- 1. Ровно один корневой элемент -->
<!-- 2. Каждый открытый тег закрыт: <a>...</a> или <a/> -->
<!-- 3. Правильная вложенность (без пересечений): -->
<b><i>ок</i></b>     <!-- ПРАВИЛЬНО -->
<!-- <b><i>плохо</b></i>   ОШИБКА: теги пересекаются -->
<!-- 4. Значения атрибутов в кавычках: id="1" -->
<!-- 5. Учёт регистра: <Tag> закрывается только </Tag> -->
<!-- 6. Спецсимволы < и & в тексте экранируются сущностями -->

Комментарии и инструкции обработки

Комментарии служат для пояснений, инструкции обработки (PI) передают команды приложению, читающему XML.

<!-- Это комментарий. Внутри нельзя писать двойной дефис -- -->

<?xml-stylesheet type="text/xsl" href="style.xsl"?>
<!-- ^ инструкция обработки (PI): говорит, какой XSLT применить -->

<?php echo "PI может нести любую команду приложению"; ?>
<!-- Общий вид PI: <?цель данные?> -->

XML против HTML (кратко)

Похожий синтаксис, но разные задачи: HTML описывает отображение страницы, XML — структуру данных.

<!-- XML: теги придумываете вы, важен смысл, правила строгие -->
<note>
  <to>Аня</to>
  <body>Текст</body>       <!-- закрывать обязательно -->
</note>

<!-- HTML: фиксированный набор тегов, парсер прощает ошибки, -->
<!-- допускает незакрытые теги (<br>, <img>), регистр не важен -->
<!-- Вывод: XML — данные и строгость, HTML — вёрстка и снисходительность -->

Практический пример: файл конфигурации

Соберём всё вместе: декларация, корень, вложенность, атрибуты, сущности и комментарии в реальном конфиге.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Конфигурация приложения -->
<configuration>

  <!-- Настройки подключения к БД через атрибуты -->
  <database host="localhost" port="5432">
    <name>app_prod</name>
    <user>admin</user>
    <!-- В пароле спецсимвол & экранирован как &amp;amp; -->
    <password>p@ss &amp;amp; key</password>
  </database>

  <!-- Список фич: повторяющиеся элементы — это нормально -->
  <features>
    <feature name="cache" enabled="true"/>
    <feature name="logs" enabled="false"/>
  </features>

  <!-- Произвольный SQL прячем в CDATA, чтобы не экранировать < и & -->
  <query>
    <![CDATA[ SELECT * FROM users WHERE age > 18 AND active = 1 ]]>
  </query>

</configuration>
<!-- Готово: валидный, well-formed XML-конфиг. -->
Поддержать проект