Конвертер XML в JSON

Конвертируйте XML в JSON: повторяющиеся элементы становятся массивами, атрибуты идут в @attributes, CDATA и текст читаются корректно и без потерь.

Всё работает в вашем браузере — данные не отправляются на сервер.

Зачем переводить XML в JSON

XML в JSON переводят по одной простой причине: JSON умеет то, чего не умеет XML. В XML у элемента нет типа, всё содержимое это текст, а повторяющиеся элементы отличаются от одиночных только числом повторов, а не самим фактом существования. Приложение, которое читает XML, обязано само догадываться, где число, где дата, где флаг, и где список, а где единственный объект. JSON отвечает на это явно: массив это массив, объект это объект, а тип записан прямо в значении. Преобразование снимает эту работу с кода. Форматтер XML приводит документ к читаемому виду, но структуру не меняет, а конвертер именно меняет: превращает дерево тегов в данные, которые можно положить в объект и отдать дальше.

Что умеет конвертер

  • Повторяющиеся элементы одного имени собираются в массив, одинарные остаются объектом
  • Переключатель «всегда массив»: даже единственный элемент оборачивается в список
  • Атрибуты либо собираются в отдельное поле @attributes, либо смешиваются с содержимым
  • Текст можно сохранить как есть или обрезать, чтобы убрать пробелы форматирования
  • Секции CDATA попадают в содержимое, комментарии пропускаются
  • Префиксы пространств имён можно отбросить или сохранить, XML-декларация читается и не попадает в результат

Как пользоваться конвертером

  1. Вставьте XML в поле ввода
  2. Выберите, куда девать атрибуты: в отдельное поле или рядом с содержимым
  3. Решите, что делать с пробелами в тексте и с префиксами пространств имён
  4. При необходимости включите «всегда массив», чтобы схема была стабильной
  5. Нажмите «Преобразовать в 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 и зачем нужен переход

Главное отличие — в типах. В XML любое значение это строка: нет чисел, нет булевых значений, нет null, нет вложенных массивов как отдельного типа. В JSON всё это есть и записано явно. XML задаёт структуру документа тегами и порядком элементов, JSON — структуру данных ключами и значениями. Отсюда и разница в применении: XML удобен для обмена между системами, где важна строгая схема документа, JSON — для передачи данных в код. Переход между ними нередко нужен именно тогда, когда старый XML-сервис отдаёт данные, а новое приложение хочет работать с объектами. Посмотрите также форматирование XML, если сначала нужно привести документ к читаемому виду.

Почему повторяющиеся элементы становятся массивом

Потому что в XML одиночный и повторяющийся элемент выглядят одинаково, и в JSON это разные типы. Строка item один раз и item пять раз — это один и тот же тег, и читатель XML обязан посмотреть на число появлений, чтобы понять, список это или единственный объект. Конвертер делает это решение за него: один элемент становится объектом, несколько — массивом. Если схема должна быть стабильной, а сегодня в выгрузке одна запись, а завтра пять, включите переключатель «всегда массив»: тогда тип поля не меняется от запуска к запуску, и код, который ждёт список, не сломается на пустой выгрузке.

Что означает поле @attributes и зачем второй режим

Так атрибуты отделены от содержимого, и это понятнее всего читается. Тег с атрибутами превращается в объект с полем @attributes, внутри которого лежат сами атрибуты, а элементы и текст стоят рядом на верхнем уровне. Ничего не смешивается, и потерять атрибут невозможно. Второй режим, смешивание с содержимым, кладёт атрибуты прямо в объект рядом с дочерними элементами: короче, но если у элемента есть атрибут с тем же именем, что и у вложенного элемента, возникнет конфликт. Режим выбирают по вкусу и по тому, что дальше будет читать результат.

Что происходит с пробелами в тексте

Формально XML пробелы не сжимает: перевод строки и отступы в тексте элемента остаются частью значения. Но в файлах, отформатированных для чтения, текст между тегами почти всегда содержит переводы строк и отступы форматирования, и в JSON они превращаются в некрасивые символы. Поэтому есть два режима. По умолчанию пробелы схлопываются и края обрезаются, и в JSON попадает содержательный текст. Режим сохранения оставляет всё как есть — он нужен, когда пробелы значимы, например в тексте с отступами или в блоке кода.

Как обрабатываются CDATA и комментарии

Секция CDATA нужна, чтобы записать в XML кусок текста, который иначе пришлось бы экранировать: HTML, SQL-запрос, регулярное выражение. Парсер читает её целиком и добавляет содержимое в текст элемента, после чего в JSON это обычная строка со всеми спецсимволами на месте. Комментарии, наоборот, ничего не несут для потребителя данных и просто пропускаются: они остаются в исходном XML, но в JSON их нет. XML-декларация вроде <?xml version="1.0" encoding="UTF-8"?> читается, проверяется на вид и тоже не попадает в результат — она описывает файл, а не данные.

Что с пространствами имён и префиксами

Пространства имён в XML — это способ развести одноимённые элементы из разных словарей: у одного документа может быть свой набор тегов, у другого — свой, и префикс показывает, к какому относится элемент. По умолчанию префикс отбрасывается, и остаётся только имя элемента: ns:item превращается в item. Так JSON остаётся читаемым, а объявления xmlns из результата убираются, потому что они описывают правила именования, а не данные. Переключатель сохраняет префикс, и тогда разные словари не схлопываются в один: ns:item и item остаются разными ключами. Выбор зависит от того, важно ли вам различие.

Можно ли вернуть JSON обратно в XML без потерь

Без потерь не получится, и причина в типах. В XML всё содержимое это строка, поэтому при обратной конвертации невозможно отличить число 42 от строки "42", а булево значение от текста "true": в исходном XML этой информации просто нет. Типы придётся восстанавливать вручную по правилам вашей предметной области. Структура же восстанавливается полностью: вложенность, повторяющиеся элементы и атрибуты. По этой же причине конвертация JSON в XML всегда требует соглашения о том, какое поле считать датой, какое — числом, а какое — флагом, и без соглашения результат будет состоять из строк.

Что делать, если XML не разбирается

Конвертер покажет, что именно не так: незакрытый тег, несовпадение имён при закрытии, значение атрибута без кавычек, два корневых элемента или незакрытая секция CDATA. Здесь важно понимать границу: XML требует ровно одного корневого элемента, все теги должны быть закрыты, а значения атрибутов обязаны быть в кавычках. Самая частая ошибка в выгрузках — несовпадающие имена при закрытии, когда тег открыли как item, а закрыли как items. Дальше помогает форматирование XML, оно показывает структуру документа и проверяет парность тегов.

Похожие инструменты