Эта статья предназначена для тех, кому волею судеб нужно разбирать большие XML-файлы, но той же волею им доступно это делать на JavaScript или CoffeeScript на NodeJS. Речь пойдёт об использовании npm-пакета xml-stream, основными свойствами которого являются:
- Событийный разбор XML на более высоком уровне абстракции чем в случае с SAX-образным парсером.
- Представление избранных участков XML в виде чистых объектных моделей (обычные объекты JavaScript) для редактирования и анализа (подобных SimpleXML в PHP) и сообщение о них в виде событий.
- Простой CSS-образный синтаксис селекторов для выбора объектов;
Для тех, кому не терпится сразу приступить к использованию библиотеки мы порекомендуем сделать
$ npm install xml-stream
и перейти к секции с примерами и документацией.
Для тех же, кто хочет точно понять с чем имеет дело и чего ожидать от предлагаемого инструмента, увидеть с какими концептуальными трудностями пришлось столкнуться в процессе отображения XML на JSON и обратно, какие архитектурные решения были приняты при разработке: что введено, и чем авторы сознательно пожертвовали, да и просто почувстовать "философию" обработки данных -- мы приглашаем прочесть всё по порядку, и самостоятельно определить свою позицию по некоторым спорным вопросам. Дать читателям такую возможность нам кажется честнее, чем просто предлагать "кота в мешке", хоть этот мешок и Open-Source'ный. Итак...
Не смотря на то, что формат JSON уверенно вытесняет XML для передачи структурированных данных, позиции XML остаются всё ещё достаточно сильными. При этом, как ни парадоксально, особенно сильны они в случаях, где передаются существенные объёмы данных -- порядка сотен мегабайт, где использование JSON, возможно, повысило бы эффективность передачи в разы. Поставщики же данных аргументируют выбор XML для сериализации следующим образом:
-
Аргумент "из коробки": СУБД, используемые для хранения данных, в которых может быть заинтересован потребитель, часто имеют эффективные средства извлечения данных сразу в виде XML (Oracle, MS SQL Server, Postgres и т.п.) Т.е. данные сразу можно "выплюнуть" из базы в формате XML.
-
против этого аргумента трудно что-то противопоставить, особенно если учесть, что стоимость хранения и передачи одного байта постоянно уменьшается. И для перепредставления данных потребуется писать специальный переходник. Меньше преобразований -- меньше нагрузка на вычислительные ресурсы, но -- самое главное -- меньше ошибок!
Однако, следует отметить, что постепенно увеличивается количество NoSQL баз, так или иначе причастных к JavaScript ([MongoDB],[CouchDB],[Redis],[Riak]), обрабатывающих серьёзный объём данных и способных выдавать "крупноколиберный" JSON.
-
-
Аргумент "от потребителя": Моделью потребления больших объёмов данных обычно является соединение типа Server-to-Server. Т.е. за данными обращается не конченый клиент, а промежуточный сервер. Cерверное же ПО, работающее с такими объёмами данных, обычно написано на языках/платформах, которые возникли в момент расцвета XML и имеют встроенные или стандартные методы для обработки XML. В то время как JSON или YAML для них являются экзотикой и часто, при переводе в адекватную для выбранного языка форму, теряют свою легковестность и привлекательность;
- Этот аргумент сдаёт позиции, но пока ещё справедлив в тех случаях, когда на стороне сервера трудится что-то написоанное на одном изиз строго-типизированных статических языков вроде C# или Java. Для таких языков сам XML вкупе с соответствующей XML-Schem'ой, является адекватным представлением строго-типизированных данных. Аргумент "от потребителя" утрачивает силу с появлением таких вещей как JSON-Schema и Kwalify, которые рано или поздно (возможно даже в другой инкарнации) позволят смотреть на JSON сквозь статическую, сторого типизированную призму; с другой стороны аргумент также теряет силу с появлением механизмов интеграции статических языков с динамическими - см. например ключевое слово dynamic в C# DLR в .NET. И уж совсем становится несостоятеленым, если серверный код написан на каком-либо из динамических языков, которые в своём большинстве имеют структуры, адекватные JSON.
-
Аргумент "от удобства": JSON себя оправдывает в случае передачи небольших объёмов, когда его можно превратить в объект целиком и потом удобно пользоваться свойствами полученного объекта, а для больших данных требуется потоковый разбор в стиле SAX-парсера, при котором вся вкусность JSON исчезает.
- Этот аргумент -- обоюдоострый. Он в равной степени направлен и за и против XML. Событийная модель разбора, будь она реализована для XML или для JSON полностью абстрагирует нас от конкретного синтаксиса разметки данных (т.е. что используется для структурирования данных - теги или фигурные скобочки с пунктуацией). Мы получаем события согласно иерархии вложенности структур данных и всё! Конечно, для XML и для JSON виды событий будут отличаться (далее мы рассмотрим это подробнее, когда затронем тему фундаментального несоответствия JSON и XML). И разница здесь скорее в том, что для XML давно существуют надёжные реализации событийных парсеров (один из наиболее популярных - это [Expat]), а для JSON они только начинают появляться.