XML от А до Я: синтаксис, структура и разбор на примерах

XML от А до Я: синтаксис, структура и разбор на примерах Полезное

XML (eXtensible Markup Language, расширяемый язык разметки) — это текстовый формат для хранения и передачи данных в виде дерева вложенных тегов, читаемого и человеком, и программой. Разработчик сам придумывает названия тегов под свою задачу — формат не навязывает готовый словарь, только правила синтаксиса.

Ниже разберем, из чего состоит XML-документ (пролог, элементы, атрибуты, правила корректности), чем XML отличается от HTML, как разобрать XML в коде на Python с реальным выводом и где формат реально применяется в 2026 году.

XML — язык разметки, а не программирования

Частая путаница: XML называют языком программирования. Это неверно. XML не содержит команд, условий и циклов, он ничего не вычисляет. Его задача — описать данные и их структуру, а обработку выполняет отдельная программа (парсер), написанная на Python, Java, C# и любом другом языке.

Проще говоря, XML — это способ записать данные так, чтобы их одинаково поняли разные системы. Один сервис сформировал XML, передал по сети, другой сервис его прочитал — независимо от платформы и языка, на которых они написаны.

Синтаксис: из чего состоит документ

Вот минимальный корректный XML-документ. На нем разберем все составные части:

<?xml version="1.0" encoding="UTF-8"?>
<note>
    <to>Анна</to>
    <from>Иван</from>
    <subject priority="high">Встреча</subject>
    <body>Давай обсудим проект в четверг.</body>
</note>

Разберем по частям:

  • Пролог — первая строка <?xml version="1.0" encoding="UTF-8"?>. Указывает версию XML и кодировку. Строка необязательна, но если она есть, то стоит строго первой, без пробелов и пустых строк перед ней.
  • Элемент — пара открывающего и закрывающего тегов и все, что между ними: <to>Анна</to>. Закрывающий тег отличается слешем: </to>.
  • Корневой элемент — единственный внешний элемент, который охватывает весь документ. Здесь это <note>. Корень в документе ровно один — двух корневых элементов быть не может.
  • Вложенность — элементы образуют дерево: <to>, <from>, <subject>, <body> вложены в <note> и являются его дочерними элементами.
  • Атрибут — пара имя-значение внутри открывающего тега, значение всегда в кавычках: priority="high".

Правила корректного документа

Документ, который соблюдает синтаксис XML, называют правильно оформленным (well-formed). Ключевые правила:

  1. Ровно один корневой элемент на весь документ.
  2. Каждый открытый тег закрыт: либо парой <tag></tag>, либо самозакрывающимся <tag/> для пустого элемента.
  3. Теги вложены без пересечений: <a><b></b></a> — верно, <a><b></a></b> — ошибка.
  4. Имена чувствительны к регистру: <Note> и <note> — разные теги.
  5. Значения атрибутов всегда в кавычках, двойных или одинарных.

Если хотя бы одно правило нарушено, парсер не станет читать документ и вернет ошибку — в отличие от браузера, который прощает битую HTML-разметку. Посмотрим на это в коде: сломанный документ, реальная ошибка, исправление.

import xml.etree.ElementTree as ET

broken = "<note><to>Аня</to><from>Иван</note>"  # тег <from> не закрыт
try:
    ET.fromstring(broken)
except ET.ParseError as err:
    print("ошибка разбора:", err)

fixed = "<note><to>Аня</to><from>Иван</from></note>"
ok = ET.fromstring(fixed)
print("после исправления корень:", ok.tag, "| детей:", len(ok))

Реальный вывод:

ошибка разбора: mismatched tag: line 1, column 30
после исправления корень: note | детей: 2

Парсер прямо указывает на несовпадение тегов и позицию — открыли <from>, а закрыли </note>. После исправления документ читается: у корня note два дочерних элемента.

Well-formed и valid: не путать

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

Правильно оформленный (well-formed) документ — тот, что соблюдает синтаксис из раздела выше. Этого достаточно, чтобы парсер его прочитал.

Валидный (valid) документ — тот, что вдобавок соответствует схеме: заранее описанному набору разрешенных элементов, их порядка и типов данных. Схему задают через DTD (более старый механизм) или XML Schema (XSD, файл .xsd — современный и более выразительный способ, поддерживает типы данных).

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

Чем XML отличается от HTML

XML и HTML внешне похожи угловыми скобками, но решают разные задачи: XML хранит и передает данные, HTML размечает страницу для показа в браузере.

Признак XML HTML
Назначение хранение и передача данных разметка страницы для отображения
Теги придумывает разработчик фиксированный набор из спецификации
Регистр тегов важен не важен
Закрытие тегов обязательно всегда часть тегов можно не закрывать
Битая разметка документ не разбирается, ошибка браузер чинит и показывает
Пустой элемент <hr/> или <hr></hr> <hr>

Форматы не конкурируют, а дополняют друг друга: XHTML — это как раз HTML, записанный по строгим правилам XML.

Как прочитать XML в коде

Данные из XML вынимает парсер. В стандартной библиотеке Python для этого есть модуль xml.etree.ElementTree. Разберем каталог книг: считаем число записей и пройдем по каждой.

import xml.etree.ElementTree as ET

data = '''<?xml version="1.0" encoding="UTF-8"?>
<catalog>
    <book id="b1">
        <title>XML для начинающих</title>
        <price currency="RUB">590</price>
    </book>
    <book id="b2">
        <title>Основы веб-разработки</title>
        <price currency="RUB">740</price>
    </book>
</catalog>'''

root = ET.fromstring(data)
print("корневой тег:", root.tag)
print("число книг:", len(root.findall("book")))
for book in root.findall("book"):
    title = book.find("title").text
    price = book.find("price")
    print(book.get("id"), "->", title, "|", price.text, price.get("currency"))

Реальный вывод:

корневой тег: catalog
число книг: 2
b1 -> XML для начинающих | 590 RUB
b2 -> Основы веб-разработки | 740 RUB

Здесь find берет вложенный элемент по имени, .text — его текст, .get("currency") — значение атрибута. Метод findall возвращает все дочерние элементы с заданным именем, по ним удобно пройти циклом.

Навигация по документу: XPath

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

import xml.etree.ElementTree as ET

data = '''<catalog>
    <book id="b1"><title>XML для начинающих</title><price>590</price></book>
    <book id="b2"><title>Основы веб-разработки</title><price>740</price></book>
    <book id="b3"><title>Python с нуля</title><price>990</price></book>
</catalog>'''

root = ET.fromstring(data)
print("все заголовки:", [t.text for t in root.findall("book/title")])
print("книга b2:", root.find("book[@id='b2']/title").text)
print("дороже 700:")
for b in root.findall("book"):
    if int(b.find("price").text) > 700:
        print(" ", b.get("id"), b.find("title").text)

Реальный вывод:

все заголовки: ['XML для начинающих', 'Основы веб-разработки', 'Python с нуля']
книга b2: Основы веб-разработки
дороже 700:
  b2 Основы веб-разработки
  b3 Python с нуля

Путь book/title собирает все заголовки, book[@id='b2'] адресует узел по атрибуту. Фильтр по цене здесь сделан обычным кодом, потому что встроенный XPath в ElementTree не сравнивает числа — для сложных выражений берут отдельную библиотеку, например lxml.

Стандарты вокруг XML

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

  • XPath — адресация и выборка узлов внутри документа (использовали выше).
  • XSLT — преобразование XML в другой формат: HTML, текст или иной XML.
  • XML Schema (XSD) и DTD — описание допустимой структуры документа для проверки валидности.
  • XQuery — язык запросов к данным в XML, ближе по духу к SQL.
  • DOM и SAX — две модели чтения документа программой: DOM грузит все дерево в память, SAX читает потоком по событиям (экономнее на больших файлах).

Где применяется XML в 2026

Несмотря на то что для веб-API чаще выбирают JSON, XML остается стандартом в целом ряде областей:

  • Конфигурационные файлы — сборка Maven (pom.xml), настройки многих Java- и .NET-приложений.
  • Офисные документы — форматы .docx и .xlsx внутри устроены как набор XML-файлов в zip-архиве (Office Open XML).
  • Векторная графика — формат SVG — это XML, описывающий фигуры и пути.
  • Каналы обновлений — ленты RSS и Atom.
  • Веб-сервисы — протокол SOAP и описания WSDL, распространенные в корпоративных и банковских интеграциях.
  • SEO и индексация — карта сайта sitemap.xml, по которой поисковики обходят страницы.

Выводы

  • XML — это язык разметки для хранения и передачи данных деревом тегов, а не язык программирования: он описывает данные, обрабатывает их отдельная программа.
  • Документ строится из пролога, единственного корневого элемента, вложенных элементов и атрибутов; правил немного, но парсер требует их соблюдения строго.
  • Well-formed — синтаксически корректный документ; valid — вдобавок соответствующий схеме (DTD или XSD); это разные уровни, и валидность нужна не всегда.
  • Читают XML парсеры: в Python это xml.etree.ElementTree, навигацию по узлам упрощает XPath.

Где применяется и что учить дальше

Разбор XML — типовая практическая задача: скрипты выгружают данные из XML-выгрузок, конфигов и лент, а результат кладут в базу или отчет. Чтобы уверенно писать такие скрипты — парсить XML и JSON, обходить деревья, обрабатывать ошибки — нужна крепкая база самого языка.

Освойте тему на практике

Освоить ее с нуля до рабочих скриптов помогает курс Python Basic. Оценить формат и уровень до старта можно на бесплатных открытых уроках Otus — это живые занятия с преподавателями.

FAQ

XML или JSON — что выбрать для нового проекта? Для веб-API и обмена между сервисами обычно берут JSON: он компактнее и проще парсится. XML уместен там, где нужны схемы с проверкой типов, преобразования через XSLT или совместимость со стандартами вроде SOAP и Office Open XML.

Чем комментарий в XML отличается от обычного текста? Комментарий заключают в <!-- ... -->, парсер его игнорирует. Внутри нельзя писать двойной дефис --, а сам комментарий не может стоять до пролога.

Как записать символ < внутри текста, чтобы парсер не принял его за тег? Спецсимволы заменяют сущностями: &lt; для <, &gt; для >, &amp; для &. Либо оборачивают текст в блок <![CDATA[ ... ]]>, где содержимое не разбирается как разметка.

OTUS Журнал