Перейти к содержимому

XML

XML — язык разметки для структурированных данных (расширяемый, создаёте свои теги). В отличие от JSON, позволяет описывать схему (XSD), навигацию (XPath), преобразование (XSLT).

Введение: Дедушка форматов обмена данными

Представьте, что вам нужно отправить документ, который содержит не только текст, но и структуру: главы, параграфы, сноски, таблицы, изображения. Вы можете написать его в Word, но как передать этот документ другой программе так, чтобы она поняла его структуру?

Для этого нужен язык, который описывает не просто данные, а их структуру. Язык, в котором вы сами определяете теги, как в HTML, но не для отображения, а для описания смысла.

XML (eXtensible Markup Language) — это язык разметки, который позволяет создавать собственные теги для описания данных. В отличие от HTML, где теги предопределены (<h1>, <p>, <table>), в XML вы сами придумываете теги: <user>, <order>, <product>.

XML появился в конце 1990-х и долгое время был стандартом для обмена данными между системами. До JSON это был главный формат для веб-сервисов (SOAP), конфигурационных файлов, офисных документов (Microsoft Office, OpenDocument). Сегодня JSON вытеснил XML из веб-API, но XML остаётся в корпоративных системах, документах, конфигурациях Java-приложений, форматах электронных документов (UBL, EBICS).

XML — это как латынь в Европе. Когда-то она была универсальным языком науки и религии. Сегодня её используют в основном в специфических сферах. Но знать её полезно, потому что на ней написаны многие важные документы и системы.

Что такое XML

XML — это текстовый формат для хранения и передачи структурированных данных. Он похож на HTML, но в HTML теги отвечают за внешний вид, а в XML — за смысл.

HTML (для отображения):

<h1>Заголовок</h1>
<p>Это абзац</p>
<ul>
    <li>Пункт 1</li>
    <li>Пункт 2</li>
</ul>

XML (для данных):

<user>
    <name>Иван Петров</name>
    <age>30</age>
    <city>Москва</city>
    <phones>
        <phone type="mobile">+7-999-123-45-67</phone>
        <phone type="home">+7-495-123-45-67</phone>
    </phones>
</user>

Ключевое слово в названии — eXtensible (расширяемый). Вы не ограничены фиксированным набором тегов. Вы создаёте теги, которые описывают ваши данные.

Основные правила синтаксиса XML

1. XML-декларация

Первая строка XML-документа — декларация. Она необязательна, но рекомендуется.

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

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

XML-документ должен иметь ровно один корневой элемент, который содержит все остальные.

<!-- Правильно: один корневой элемент -->
<users>
    <user>Иван</user>
    <user>Петр</user>
</users>

<!-- Неправильно: два корневых элемента -->
<user>Иван</user>
<user>Петр</user>

3. Теги

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

<!-- Закрытый тег -->
<name>Иван</name>

<!-- Самозакрывающийся тег (пустой элемент) -->
<image src="photo.jpg"/>

4. Атрибуты

Атрибуты — это дополнительные свойства тега. Значения всегда в кавычках (одинарных или двойных).

<user id="123" status="active">
    <name>Иван</name>
</user>

<order status="delivered" priority="high"/>

5. Регистр имеет значение

XML чувствителен к регистру. <User> и <user> — разные теги.

6. Пробелы сохраняются

В отличие от HTML, XML сохраняет пробелы и переносы строк (если явно не указано иное).

Основные компоненты XML

Элементы (Elements)

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

<person>
    <name>Иван</name>
    <age>30</age>
</person>

Содержимое элемента может быть:

  • Текст: <name>Иван</name>
  • Дочерние элементы: <person><name>Иван</name></person>
  • Смешанное (текст + элементы): <p>Текст с <b>выделением</b></p>
  • Пустое: <empty/>

Атрибуты (Attributes)

Атрибуты — это метаданные элемента.

<product id="p123" currency="RUB">
    <name>iPhone</name>
    <price>50000</price>
</product>

Когда использовать атрибут, а когда элемент?

КритерийАтрибутЭлемент
Метаданныеid="123", type="user"
Множественные значенияНет (один атрибут)Да (<phone>...</phone>)
СтруктураПлоскаяВложенная
Длинный текстНетДа

Пример: атрибут vs элемент

<!-- Атрибуты (метаданные) -->
<user id="123" status="active">
    <name>Иван</name>
</user>

<!-- Элементы (данные) -->
<user>
    <id>123</id>
    <status>active</status>
    <name>Иван</name>
</user>

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

Пространства имён позволяют использовать одинаковые теги из разных словарей в одном документе.

<root xmlns:book="http://example.com/book"
      xmlns:author="http://example.com/author">
    
    <book:title>Война и мир</book:title>
    <author:name>Лев Толстой</author:name>
    
</root>

Когда нужно: Объединение данных из разных систем, SOAP, XSLT.

Валидный vs правильный XML

ТерминЧто значит
Well-formed (правильно сформированный)Соблюдает синтаксис XML. Нет ошибок в тегах, кавычках, закрытии элементов.
Valid (валидный)Соответствует схеме (DTD, XSD). Дополнительно проверяет структуру, типы данных, обязательность элементов.

Well-formed (синтаксис)

Этот документ правильно сформирован:

<?xml version="1.0"?>
<user>
    <name>Иван</name>
    <age>30</age>
</user>

Этот — нет (не закрыт тег name):

<?xml version="1.0"?>
<user>
    <name>Иван
    <age>30</age>
</user>

Valid (схема)

Валидность проверяется по DTD или XSD.

DTD (Document Type Definition) — старый способ:

<!DOCTYPE user [
    <!ELEMENT user (name, age)>
    <!ELEMENT name (#PCDATA)>
    <!ELEMENT age (#PCDATA)>
]>
<user>
    <name>Иван</name>
    <age>30</age>
</user>

XSD (XML Schema Definition) — современный способ:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="user">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="name" type="xs:string"/>
                <xs:element name="age" type="xs:integer"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

XSD типы данных:

ТипОписание
xs:stringСтрока
xs:integerЦелое число
xs:decimalДесятичное число
xs:booleantrue/false
xs:dateДата (YYYY-MM-DD)
xs:dateTimeДата и время
xs:emailEmail (не стандарт, нужен pattern)

XPath и XQuery

XPath (язык запросов к XML)

XPath позволяет навигировать по XML-документу и выбирать элементы.

<bookstore>
    <book category="fiction">
        <title>Война и мир</title>
        <author>Лев Толстой</author>
        <price>500</price>
    </book>
    <book category="science">
        <title>Краткая история времени</title>
        <author>Стивен Хокинг</author>
        <price>800</price>
    </book>
</bookstore>

XPath выражения:

ВыражениеРезультат
/bookstore/bookВсе книги
/bookstore/book[1]Первая книга
/bookstore/book[@category='fiction']Книги категории “fiction”
/bookstore/book/priceЦены всех книг
/bookstore/book/price/text()Тексты цен

XQuery (язык запросов, как SQL для XML)

for $book in doc("books.xml")/bookstore/book
where $book/price > 600
return $book/title

XSLT (преобразование XML)

XSLT позволяет преобразовывать XML в другие форматы (HTML, текст, другой XML).

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <html>
            <body>
                <table border="1">
                    <tr>
                        <th>Название</th>
                        <th>Цена</th>
                    </tr>
                    <xsl:for-each select="bookstore/book">
                        <tr>
                            <td><xsl:value-of select="title"/></td>
                            <td><xsl:value-of select="price"/></td>
                        </tr>
                    </xsl:for-each>
                </table>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

CDATA (символьные данные)

CDATA позволяет вставлять любой текст, включая символы, которые XML интерпретирует как разметку (<, >, &).

<code>
    <![CDATA[
        if (x < 10 && y > 20) {
            console.log("Hello & welcome");
        }
    ]]>
</code>

Без CDATA пришлось бы экранировать: &lt;, &gt;, &amp;.

XML в языках программирования

Python (xml.etree.ElementTree)

import xml.etree.ElementTree as ET

# Парсинг
tree = ET.parse('users.xml')
root = tree.getroot()

# Поиск элементов
for user in root.findall('user'):
    name = user.find('name').text
    age = user.find('age').text
    print(f"{name}: {age}")

# Создание XML
root = ET.Element('users')
user = ET.SubElement(root, 'user')
name = ET.SubElement(user, 'name')
name.text = 'Иван'
age = ET.SubElement(user, 'age')
age.text = '30'

tree = ET.ElementTree(root)
tree.write('output.xml', encoding='utf-8', xml_declaration=True)

Java (JAXB, DOM, SAX)

import javax.xml.parsers.*;
import org.w3c.dom.*;

// DOM парсер
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("users.xml");

NodeList users = doc.getElementsByTagName("user");
for (int i = 0; i < users.getLength(); i++) {
    Element user = (Element) users.item(i);
    String name = user.getElementsByTagName("name").item(0).getTextContent();
    System.out.println(name);
}

JavaScript

// DOMParser
const parser = new DOMParser();
const xmlString = `<user><name>Иван</name><age>30</age></user>`;
const doc = parser.parseFromString(xmlString, "application/xml");

const name = doc.querySelector("name").textContent;
console.log(name);

XML vs JSON

ХарактеристикаXMLJSON
ЧитаемостьСредняяОтличная
РазмерБольшойМаленький
Схема (валидация)XSD, DTDJSON Schema
Типы данныхЧерез XSDВстроенные
Пространства имёнДаНет
КомментарииДаНет
XPath / XQueryДаНет
XSLTДаНет
Поддержка в браузерахОтличнаяОтличная
Популярность в APIНизкая (< 1%)Высокая (99%)

Когда JSON лучше: REST API, веб-приложения, конфиги, логи.

Когда XML лучше: Сложные документы, SOAP, корпоративные интеграции, офисные форматы (DOCX, XLSX), системы с жёсткими схемами.

XML в реальных форматах

Многие известные форматы основаны на XML.

ФорматНазначение
SOAPВеб-сервисы (корпоративные)
RSS / AtomЛенты новостей
SVGВекторная графика
XHTMLHTML, совместимый с XML
DOCX, XLSX, PPTXMicrosoft Office (ZIP + XML)
ODT, ODS, ODPOpenDocument (ZIP + XML)
XSLTПреобразование XML
XSDСхемы XML
RDF / OWLСемантический веб
EBICSБанковские транзакции (Европа)
UBLЭлектронные счета (стандарт)
FpMLФинансовые деривативы
GPXGPS треки

Проблемы и ограничения XML

Избыточность

<!-- XML: 100 байт -->
<user><name>Иван</name><age>30</age></user>

<!-- JSON: 40 байт -->
{"name":"Иван","age":30}

Сложность парсинга

DOM (Document Object Model) загружает весь документ в память. Для больших файлов (сотни МБ) это проблема. Есть SAX (Streaming API for XML) — событийный парсер, но он сложнее.

Человеко-нечитаемый (в больших объёмах)

Несмотря на разметку, большие XML-файлы сложно читать и редактировать вручную.

Отсутствие встроенных типов данных

В JSON есть числа, булевы, null. В XML всё — строки. Типы данных нужно описывать в XSD.

Когда использовать XML сегодня

Идеальные сценарии

СценарийПочему XML
Офисные документы (DOCX, XLSX)Стандарт де-факто
Векторная графика (SVG)Стандарт W3C
Сложные документы с схемойXSD валидация, XSLT преобразование
SOAP веб-сервисыСтандарт корпоративных систем
Электронные счета (UBL)Юридические стандарты
Банковские транзакции (EBICS)Европейский банковский стандарт
Конфигурации Java-приложенийMaven, Spring (хотя YAML наступает)

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

СценарийПочему не XML
REST APIJSON проще и легче
Конфигурационные файлыYAML или JSON удобнее
ЛогиJSON Lines или обычный текст
Внутренние системы без жёстких схемJSON или Protobuf

Распространённые ошибки

Ошибка 1: Не закрыт тег

<!-- Плохо -->
<user>
    <name>Иван
</user>

<!-- Хорошо -->
<user>
    <name>Иван</name>
</user>

Ошибка 2: Регистр в тегах

<!-- Плохо (User и user — разные теги) -->
<User>
    <name>Иван</name>
</User>

Ошибка 3: Кавычки у атрибутов

<!-- Плохо -->
<user id=123>

<!-- Хорошо -->
<user id="123">

Ошибка 4: Неправильные символы в тексте

<!-- Плохо (XML думает, что это теги) -->
<code>if (x < 10 && y > 20)</code>

<!-- Хорошо (экранирование) -->
<code>if (x &lt; 10 &amp;&amp; y &gt; 20)</code>

<!-- Или CDATA -->
<code><![CDATA[if (x < 10 && y > 20)]]></code>

Ошибка 5: Два корневых элемента

<!-- Плохо -->
<user>Иван</user>
<user>Петр</user>

<!-- Хорошо -->
<users>
    <user>Иван</user>
    <user>Петр</user>
</users>

Резюме для системного аналитика

  1. XML — язык разметки для структурированных данных. В отличие от JSON, позволяет описывать не только данные, но и их структуру, типы, правила валидации.

  2. Синтаксис: теги в угловых скобках, атрибуты в кавычках, один корневой элемент, регистр важен.

  3. Well-formed (правильный синтаксис) vs Valid (соответствие схеме). Well-formed обязателен, Valid — опционален (но рекомендуется для сложных систем).

  4. XSD (XML Schema Definition) — современный язык описания схем. Заменяет старый DTD. Позволяет описывать типы данных, обязательность, структуру.

  5. XPath — язык навигации по XML. XQuery — язык запросов (как SQL). XSLT — преобразование XML в другие форматы.

  6. XML тяжелее JSON. В 2-5 раз больше размер, медленнее парсинг, сложнее чтение человеком.

  7. XML живёт в специфических нишах: офисные форматы (DOCX), векторная графика (SVG), SOAP, банковские и юридические стандарты.

Проверка знаний

Вопрос 1 из 4
Что является ключевой особенностью XML?
Какое правило синтаксиса XML обязательно?
Что означает, что XML-документ valid?
Где XML по-прежнему особенно уместен?

Вопросы, где были ошибки