Преобразовать XML в JSON и JSON в XML: атрибуты отдельным ключом, повторяющиеся элементы как массив, текстовые узлы и сохранение вложенности. Выбор способа записи атрибутов и значений, имя корневого элемента. Всё считается в браузере.
Разобрать XML и записать его в JSON: как записывать атрибуты, текстовые узлы и повторяющиеся элементы — настраивается ниже
Каждый атрибут становится отдельным ключом: <user id="7"> → "@id": "7". Собака отделяет атрибут от дочернего элемента с тем же именем
Элемент без атрибутов и детей становится значением: <name>Чайник</name> → "name": "Чайник". Текст рядом с вложенными тегами всё равно уходит в «#text»
В XML типов нет, поэтому результат ничего не додумывает: «2990» остаётся строкой
На каждый уровень вложенности — два пробела
XML никуда не ушёл: в нём отдают данные выгрузки из 1С и CRM, на нём работают SOAP, RSS, SVG и большинство файлов настроек. Но инструменты вокруг сегодня чаще говорят на JSON — скрипты, таблицы, запросы по JSONPath, загрузчики в базы. Перевод нужен не потому, что один формат лучше другого, а потому, что данные остаются теми же, а окружение вокруг них другое.
Инструмент строит по XML дерево элементов и записывает его в JSON по вашим настройкам: атрибуты отдельным ключом с собакой, без префикса или не выгружаются вовсе; повторяющиеся дочерние элементы собираются в массив; текст листа становится значением элемента или отдельным ключом «#text»; числа и логические значения распознаются либо остаются строками. Отступы — от нуля до табуляции — влияют только на вид файла. Часть сведений при переводе теряется навсегда: комментарии, DOCTYPE и порядок текста между тегами в JSON не выражаются, и обратный перевод даст уже не исходный документ.
В обратную сторону инструмент собирает XML из JSON по тем же правилам, только наоборот: ключ с собакой становится атрибутом, ключ «#text» — текстом элемента, массив — несколькими элементами с одним именем, вложенный объект — вложенными элементами. Имя корневого элемента задаётся отдельно: в JSON у корня имени нет — объект это набор ключей, а массив и вовсе список значений, — поэтому без этой настройки корень назывался бы никак, и её значение по умолчанию root приходится менять руками. Ключи, которые в XML именем быть не могут, — пробел, начало с цифры, двоеточие — приводятся к допустимому виду заменой знака на подчёркивание: выбрасывать знак значило бы склеить «цена руб» и «цена-руб» в одно имя, а такой файл прочитался бы с другими данными. Амперсанд, угловые скобки и кавычки экранируются: без этого собранный файл разобрался бы иначе, чем выглядит. Заметная разница с разбором в том, что сборка идёт строкой, без участия браузерного разборщика, — и потому работает одинаково всюду, где выполняется JavaScript.
Разбор, запись и подсчёт размера выполняются в браузере на JavaScript: XML не отправляется на сервер и не сохраняется. Это важно, когда в файле выгрузка с персональными данными, конфигурация с адресами и ключами доступа или ответ внутренней системы, который не должен уходить наружу.
За это отвечает настройка «Атрибуты». По умолчанию каждый атрибут становится отдельным ключом с собакой: <user id="7"> превращается в "@id": "7". Собака нужна не для красоты: у записи <user id="7"><id>7</id></user> ключ id от атрибута и ключ id от дочернего элемента совпали бы, и одно из значений исчезло бы из результата. Режим «Ключом как есть» пишет ключом само имя атрибута — он годится, когда таких совпадений в файле нет. Режим «Не выгружать» выбрасывает атрибуты совсем: в JSON остаётся только структура элементов.
Флажком «Одинаковые дочерние элементы — всегда массив», он включён по умолчанию. Если у элемента два и более ребёнка с одним именем, они становятся массивом в порядке появления: <tag>кухня</tag><tag>техника</tag> превращается в "tag": ["кухня", "техника"]. Одиночный ребёнок остаётся обычным значением, а не массивом из одного элемента: так JSON короче, а структура — точнее. Если флажок снять, массив не собирается и остаётся только последний ребёнок с таким именем: остальные из файла пропадут.
Настройка «Текстовые узлы» решает только тот случай, когда у элемента нет ничего, кроме текста. В режиме «Значением элемента» такой элемент становится значением: <name>Чайник</name> становится "name": "Чайник". Если же внутри есть и текст, и дочерние теги — <p>Текст <b>жирный</b> конец</p>, — выразить текст значением нельзя, и он попадает в ключ "#text" рядом с детьми, причём в любом режиме. Порядок при этом теряется: ключ "#text" один, и по нему видно, что текст в элементе был, но не то, где именно он стоял между тегами. Режим «Ключ #text» записывает так всегда, в том числе листья.
По умолчанию выбран режим «Всё строками»: в XML типов нет, «2990» и 2990 в нём неразличимы, поэтому результат остаётся текстом и ничего не теряет. Режим «Определять автоматически» превращает 123 и -4.5 в числа, а слова true, false и null — в логическое значение и null. Но часть строк он намеренно оставляет строками: 007 — из-за ведущего нуля (числом он стал бы 7), а 1.2.3 или 8-800-555-35-35 — потому что это не число, а идентификатор или телефон. Две тонкости, о которых стоит знать заранее: слово null в тексте станет пустым значением, а длинный идентификатор из 19 цифр потеряет последние — точность числа в JSON ограничена. Для выгрузок с такими полями надёжнее режим «Всё строками».
Префиксы не трогаются: <soap:Body> становится ключом "soap:Body", атрибут xsi:type — ключом "@xsi:type". Так значение остаётся ровно тем, что было в файле, а разбирать префикс дальше приходится тому, кто читает JSON: склеивать его с адресом пространства имён или срезать инструмент не берётся. CDATA читается как обычный текст: <![CDATA[<b>текст</b>]]> становится строкой "<b>текст</b>" — содержимое не экранируется заново, теги внутри просто часть строки. Комментарии, инструкции обработки и DOCTYPE в JSON не попадают вовсе: дерево строится только из элементов, и объявление <!DOCTYPE ...> с сущностями в результат не переносится.
XML и JSON описывают одно и то же дерево, но окружение вокруг них разное. JSON разбирается в браузере одной строкой, сразу становится объектом и дальше идёт в скрипт, в таблицу, в запрос по JSONPath или в выгрузку. Для XML то же самое требует разбора с учётом пространств имён и схемы. Перевод нужен, когда данные остаются прежними, а инструменты вокруг них — из мира JSON. Обратная сторона в том, что часть сведений о форме документа при этом теряется: атрибут, порядок текста и комментарии в JSON выражаются соглашениями, а не языком, и обратный перевод даст уже не тот файл, что был.
Переключите направление на «JSON в XML»: настройки панели сменятся, а в поле вставляется уже JSON — атрибуты, текстовые узлы и типы значений в этой стороне не настраиваются, потому что вопрос ставится иначе. Разбор идёт встроенным JSON.parse, и ошибка показывается так же, как у XML: текст движка, строка и столбец. Читается JSON по тем же соглашениям, по которым был записан: ключ с собакой становится атрибутом (@id → id="p-1"), ключ «#text» — текстом элемента, массив — несколькими элементами с одним именем, вложенный объект — вложенными элементами. Имя корневого элемента задаётся настройкой: в JSON у корня имени нет — объект это набор ключей, а массив и вовсе список значений, — поэтому по умолчанию корень называется root, а элементы массива на верхнем уровне получают имя item. Ключи, которые в XML именем быть не могут, — пробел, начало с цифры, двоеточие — заменяются подчёркиванием: иначе файл не разобрал бы никто. Флажок «Объявлять версию и кодировку» добавляет в начало строку объявления, а «Отступ» тот же, что и в обратную сторону: «Без отступов» пишет результат одной строкой.
Нет, и это не ошибка инструмента: часть сведений об XML в JSON просто не выражается, поэтому получается другое, хотя и равнозначное дерево. Имя корневого элемента в JSON не хранится — обратно корень называется по настройке, и у исходного <catalog> после круга выйдет <root>, если имя не задать руками. Атрибуты становятся обычными ключами, и порядок их в теге сохраняется лишь потому, что JSON помнит порядок ключей; но если атрибут был выключен настройкой «Не выгружать», брать его обратно неоткуда. Комментарии, объявление <?xml?>, DOCTYPE и инструкции обработки в JSON не попадают вовсе — это не элементы, и вернуть их нечем. Порядок текста между тегами теряется: текст собирается в один ключ «#text», а на обратном пути ставится перед детьми, а не туда, где стоял. Отступы и переводы строк исходника — оформление, а не данные: обратный файл форматируется по своей настройке. Наконец, типы: в режиме «Всё строками» <price>2990</price> вернётся текстом, и это точный ответ — в XML число и строка «2990» неразличимы, так что терять тут нечего. Побитово совпадёт только тот файл, который сам был собран из этого JSON при тех же настройках.
Нет. Разбирают данные встроенные средства браузера: XML — DOMParser, JSON — JSON.parse, — а запись делает JSON.stringify в одну сторону и сборка строки в другую; всё это выполняется в самой странице: файл не передаётся по сети, не сохраняется и не попадает в логи. Отключите интернет и продолжите работу: результат останется на месте. Обратная сторона в том, что при обновлении вкладки вставленный текст пропадёт — историю сайт не ведёт, поэтому готовый JSON или XML лучше сразу скачать файлом.