Конвертер XML в JSON
Конвертируйте XML в JSON: повторяющиеся элементы становятся массивами, атрибуты идут в @attributes, CDATA и текст читаются корректно и без потерь.
Зачем переводить XML в JSON
XML в JSON переводят по одной простой причине: JSON умеет то, чего не умеет XML. В XML у элемента нет типа, всё содержимое это текст, а повторяющиеся элементы отличаются от одиночных только числом повторов, а не самим фактом существования. Приложение, которое читает XML, обязано само догадываться, где число, где дата, где флаг, и где список, а где единственный объект. JSON отвечает на это явно: массив это массив, объект это объект, а тип записан прямо в значении. Преобразование снимает эту работу с кода. Форматтер XML приводит документ к читаемому виду, но структуру не меняет, а конвертер именно меняет: превращает дерево тегов в данные, которые можно положить в объект и отдать дальше.
Что умеет конвертер
- Повторяющиеся элементы одного имени собираются в массив, одинарные остаются объектом
- Переключатель «всегда массив»: даже единственный элемент оборачивается в список
- Атрибуты либо собираются в отдельное поле @attributes, либо смешиваются с содержимым
- Текст можно сохранить как есть или обрезать, чтобы убрать пробелы форматирования
- Секции CDATA попадают в содержимое, комментарии пропускаются
- Префиксы пространств имён можно отбросить или сохранить, XML-декларация читается и не попадает в результат
Как пользоваться конвертером
- Вставьте XML в поле ввода
- Выберите, куда девать атрибуты: в отдельное поле или рядом с содержимым
- Решите, что делать с пробелами в тексте и с префиксами пространств имён
- При необходимости включите «всегда массив», чтобы схема была стабильной
- Нажмите «Преобразовать в JSON» и скопируйте результат
Как устроено преобразование
XML разбирается собственным небольшим парсером. Он читает последовательность токенов: открывающий тег с атрибутами, закрывающий тег, текст между ними, комментарии, инструкции обработки, секции CDATA и XML-декларацию. Разбор идёт рекурсивно: каждый элемент читает своих детей, пока не встретит собственный закрывающий тег; несовпадение имён считается ошибкой с указанием, какой тег закрывается не тем. Дальше по готовому дереву строится JSON. Текст одного уровня собирается в группы по имени, группа из одного элемента становится значением, группа из нескольких — массивом. Атрибуты уходят в отдельный объект с префиксом @, чтобы не пересекаться с именами элементов, а текст без дочерних элементов попадает в поле #text. Схема получается предсказуемой: одноимённые элементы всегда одного типа.
Что получается из разного XML
| XML на входе | Что сделано | JSON на выходе |
|---|---|---|
| <book><title>A</title></book> | одиночный элемент стал объектом | {"book":{"title":"A"}} |
| <book><title>A</title></book><book><title>B</title></book> | два одноимённых элемента стали массивом | {"book":[{"title":"A"},{"title":"B"}]} |
| <item id="7"><name>Гайка</name></item> | атрибут ушёл в @attributes | {"item":{"@attributes":{"id":"7"},"name":"Гайка"}} |
| <item id="7"><name>Гайка</name></item> | атрибут смешан с содержимым | {"item":{"id":"7","name":"Гайка"}} |
| <item><name>Гайка</name></item> | одиночный элемент обёрнут в массив | {"item":[{"name":"Гайка"}]} |
| <d><![CDATA[a < b]]></d> | CDATA попал в текст без экранирования | {"d":"a < b"} |
| <d><!-- заметка -->текст</d> | комментарий пропущен | {"d":"текст"} |
| <r xmlns:ns="u"><ns:a>1</ns:a></r> | префикс пространства имён отброшен | {"a":"1"} |
| <r xmlns:ns="u"><ns:a>1</ns:a></r> | префикс пространства имён сохранён | {"ns:a":"1"} |
| <?xml version="1.0"?><a>1</a> | XML-декларация прочитана и отброшена | {"a":"1"} |
| <a> много пробелов </a> | пробелы схлопнуты и края обрезаны | {"a":"много пробелов"} |
| <a> много пробелов </a> | пробелы сохранены как есть | {"a":" много пробелов "} |
Первые строки таблицы — это схема по умолчанию, дальше показано, как её меняют переключатели.
Где XML и JSON встречаются рядом
Первый и самый частый сюжет — старая система отдаёт данные в XML, а новое приложение написано на JSON. Это обычная история миграции: контракт не меняют, а слой адаптации переводят на удобный формат. Второй сюжет — интеграции. Многие публичные API отдают XML, потому что формат закрепился в 1990-х и менять его никто не хочет, а разбирать XML в прикладном коде неудобно. Третий — выгрузки и импорты: XML используют как промежуточный формат между системами, у которых нет общей базы, и дальше по цепочке файл превращается в JSON для приложения или в таблицу для отчёта.
Четвёртый сюжет — конфигурация и метаданные. Файлы вроде sitemap.xml или выгрузок каталога приходят в XML, а внутри приложения им удобнее быть объектом. И наконец, обратное направление: JSON в XML нужно там, где принимающая система говорит только на XML, а данные уже живут в JSON. В этом наборе есть и обратный путь — конвертер JSON в YAML и форматирование JSON, если структуру нужно привести к читаемому виду перед разбором.
- Старая система отдаёт XML, приложение работает с JSON
- Публичный API с XML-контрактом
- Выгрузка каталога или sitemap в формате XML
- Промежуточный файл при обмене между системами
- Разбор метаданных конфигурации в объект
- Обратный путь: JSON в XML для строгого получателя
Где XML спотыкается о JSON
Первая проблема — типы. Число, дата и флаг в XML неотличимы от строк, поэтому любая выгрузка требует договорённостей: вот это поле считать датой в формате ISO, вот это целым числом, вот это флагом. Без договорённостей данные останутся строками, и сравнение дат в коде превратится в сравнение текста, которое почти всегда даёт неверный результат. Вторая проблема — повторяющиеся элементы. Один item и пять item выглядят одинаково, поэтому тип поля в JSON зависит от того, что попало в выгрузку сегодня. Решение — режим «всегда массив», при котором тип не гуляет.
Третья проблема — атрибуты. Они не являются элементами, но несут смысл: идентификатор, единица измерения, роль. Если положить их в объект без разбора, можно случайно перепутать атрибут с вложенным элементом, особенно когда имена совпадают. Отдельное поле @attributes снимает риск. Четвёртая — текст и форматирование. Файл, разбитый на строки ради читаемости, при наивном разборе даст значения с переводами строк и отступами, и любое сравнение строк в коде после этого перестанет работать. Пятая — обратная конвертация: типы, потерянные при переходе в XML, уже не вернуть, и их приходится восстанавливать по правилам.
- Числа, даты и флаги приходят строками
- Тип поля меняется, если элемент встречается один раз
- Атрибуты неотличимы от вложенных элементов без договорённости
- Пробелы форматирования попадают в значения
- Обратная конвертация не восстанавливает типы
- Порядок элементов в XML значим, а в JSON — нет
Разбор примера по шагам
Возьмём каталог из двух книг с атрибутами. Разбор идёт по токенам: сначала XML-декларация, её версия и кодировка запоминаются, но в результат не попадают. Затем комментарий, который пропускается. Потом открывающий тег catalog, у него атрибутов нет, поэтому для него в JSON не будет отдельного поля. Внутри идут два элемента book с атрибутами id и lang. У первого book есть дочерний элемент price с атрибутом currency, и потому price станет объектом с полем @attributes и полем #text, в котором лежит текст 1990.
Когда два элемента book одинакового имени собраны вместе, они превращаются в массив. Элементы title и price внутри каждой книги разные, они не повторяются, поэтому остаются объектами или строками. Второй book без атрибута lang даёт объект с одним полем, и разница между двумя книгами видна прямо в JSON. Такой разбор даёт предсказуемую схему: набор одноимённых элементов всегда массив, одиночный — объект, текст без детей — поле #text, атрибуты — отдельное поле @attributes. Проверить исходный XML помогает форматирование XML с подсветкой парности тегов.
Что происходит с каждым элементом документа
| Элемент | Действие | В JSON |
|---|---|---|
| XML-декларация | читается, кодировка запоминается | в результат не попадает |
| Комментарий | пропускается | в результат не попадает |
| Корневой элемент | его дети становятся верхним уровнем | {"book": [...]}, а не {"catalog": {...}} |
| Атрибут | кладётся в @attributes | {"id":"b1"} |
| Повторяющийся элемент | собирается в массив | "book": [ ... ] |
| Одиночный элемент | остаётся объектом | "title": "SQL" |
| Элемент с текстом и атрибутами | объект с @attributes и #text | {"@attributes":{...},"#text":"1990"} |
| CDATA | содержимое становится текстом | "a < b" |
| Пробелы в тексте | схлопываются или сохраняются | зависит от режима |
| Префикс пространства имён | отбрасывается или остаётся | "item" или "ns:item" |
Разбор идёт одним проходом по документу, поэтому размер файла почти не влияет на скорость.
С чем сравнивать и что применять рядом
Конвертер XML в JSON отвечает на вопрос «как данные выглядят в виде объекта». Форматтер XML отвечает на другой: «как выглядит сам документ». Это разные задачи, и часто они идут одна за другой: сначала приводят файл к читаемому виду с отступами, потом смотрят на структуру и конвертируют. Ещё один частый сосед — сравнение: когда формат приведён к единому виду, diff показывает изменения данных, а сравнение JSON и разница текстов умеют показывать их построчно.
Дальше по цепочке обычно стоит форматирование: форматирование JSON приводит результат к читаемому виду, JSON в YAML превращает его в YAML, если дальше нужна конфигурация, а конвертер JSON в CSV помогает выгрузить таблицей. Если же задача обратная — привести JSON к виду, который понимает XML-система, — поможет минификатор и те же правила соглашений о типах, о которых шла речь выше.
- Форматтер XML меняет вид, конвертер меняет формат
- Часто конвертируют после форматирования, а не наоборот
- Единый формат нужен, чтобы diff показывал данные
- После конвертации результат стоит отформатировать
- Обратная конвертация требует соглашений о типах
- Для JSON есть отдельные инструменты каждого шага
Частые вопросы
Чем XML отличается от JSON и зачем нужен переход
Почему повторяющиеся элементы становятся массивом
Что означает поле @attributes и зачем второй режим
Что происходит с пробелами в тексте
Как обрабатываются CDATA и комментарии
Что с пространствами имён и префиксами
Можно ли вернуть JSON обратно в XML без потерь
Что делать, если XML не разбирается
Похожие инструменты
Починка JSON
Восстановление битого JSON: комментарии, кавычки, висячие запятые, переносы строк
Форматирование и валидация JSON
Форматирование, украшение, валидация и минификация JSON с древовидным просмотром
Форматирование XML
Форматирование, украшение, минификация и валидация XML документов
Конвертер CSV в JSON
Конвертация данных CSV в формат массива JSON с настраиваемыми разделителями
JSON в TypeScript
Сгенерируйте TypeScript-интерфейсы из любого JSON — с вложенными объектами и массивами.
Конвертер JSON в CSV
Конвертация массива JSON в формат CSV с автоопределением столбцов
Конвертер JSON в YAML
Конвертация данных JSON в формат YAML с правильными отступами
Конвертер YAML в JSON
Конвертация данных YAML в формат JSON с поддержкой вложенных структур