XML в JSON

Преобразуйте XML-документы в JSON в вашем браузере. Сохраняйте атрибуты под ключами с префиксом @, сворачивайте повторяющиеся элементы в массивы и при необходимости приводите числа, логические значения и null.

Читайте XML как дерево объектов, которым он всегда хотел быть. Вставьте XML-документ и получите JSON. Атрибуты сохраняются под ключами с префиксом @, повторяющиеся элементы сворачиваются в массивы, а приведение типов включается опционально, поэтому идентификаторы сохраняют ведущие нули.

Вывод JSON

Три проблемы, которые должен решить любой конвертер XML в JSON

Атрибутам некуда деться естественно

XML проводит чёткую грань между атрибутами и дочерними элементами. <user id="7"><name>Ada</name></user> означает нечто иное, чем <user><id>7</id><name>Ada</name></user>, хотя большинство приложений обрабатывают их одинаково. В JSON нет эквивалентного различия, поэтому конвертер должен либо отбросить атрибуты, либо придумать для них место.

Широко используемое соглашение, применяемое и здесь, добавляет префикс @ к ключам атрибутов и сохраняет текст элемента под #text, когда у элемента есть и атрибуты, и содержимое. Так первый пример становится {"user": {"@id": "7", "name": "Ada"}}. Префикс не является частью какого-либо стандарта, но он достаточно распространён, чтобы большинство последующего кода распознавало его, и сохраняет обратимость преобразования. Отключение атрибутов даёт более чистый вывод, когда вы знаете, что атрибуты — это метаданные, которые вам не нужны.

Один элемент или список из одного?

Это проблема без правильного ответа. В XML родитель с одним дочерним <item> и родитель с пятью выглядят структурно похоже, но они должны стать единичным объектом и массивом соответственно — и ничто в документе не говорит вам, что имела в виду схема. Инструмент без схемы должен угадывать по тому, что он видит.

Правило здесь — сворачивать повторяющиеся имена соседних элементов в массив и оставлять одинокий элемент единичным значением. Это соответствует интуиции при чтении, но означает, что код, потребляющий вывод, должен обрабатывать обе формы, поскольку список, который сегодня случайно имеет одну запись, выдаст объект, а не массив из одного элемента. Когда вы контролируете потребителя, нормализуйте с помощью чего-то вроде [].concat(value) перед итерацией.

Всё в XML — это строка

В XML-документе без схемы типов нет. <count>42</count> и <sku>0042</sku> — это просто текст, и только человек или XSD знает, что одно является числом, а другое — идентификатором, который должен сохранять свои нули.

Именно поэтому приведение типов — это флажок, а не значение по умолчанию. Когда он включён, значения преобразуются только при точном обратном преобразовании — числовая строка становится числом, только если форматирование её обратно даёт идентичный текст, что защищает 0042, +7 и 1e999. true, false и пустые элементы становятся логическими значениями и null. Когда он выключен, каждое значение остаётся строкой, что безопаснее для идентификаторов, номеров телефонов, почтовых индексов и любого целого больше 2^53, где точность чисел JavaScript молча исказила бы значение.

Примечание с открытым исходным кодом: реализовано на чистом JavaScript без сторонних библиотек.

Часто задаваемые вопросы

Загружается ли мой XML куда-либо?
Нет. Разбор использует встроенный в браузер DOMParser, а JSON создаётся локально, поэтому документ никогда не покидает страницу.
Как представляются атрибуты?
Как ключи с префиксом @, вместе с дочерними элементами. Если у элемента есть и атрибуты, и текст, текст сохраняется под ключом #text.
Почему один элемент не стал массивом?
Без схемы ничто не указывает, означает ли один дочерний элемент единичное значение или список из одного. Повторяющиеся имена становятся массивами; одинокий элемент остаётся единичным значением.
Что делает приведение типов?
Он преобразует числовые, логические и пустые значения из текста. Числа преобразуются только при точном обратном преобразовании, поэтому 0042 и +7 остаются строками.
Стоит ли оставить приведение выключенным?
Да, для идентификаторов, номеров телефонов, почтовых индексов и целых чисел больше 2^53, где точность чисел JavaScript округлила бы значение без предупреждения.
Почему я получаю ошибку некорректного XML?
Документ не является корректно сформированным: незакрытые или несоответствующие теги, неэкранированные & или <, или больше одного корневого элемента — обычные причины.