Thursday, January 27, 2011

pugixml - light-weight C++ XML processing library

Я долгое время использовал в своих проектах msxml. Чтобы было проще работать написал обертку, которая прячет API парсера, а наружу отдает более простые методы. Чтобы спать спокойно к дистрибутиву прикладывал msxml.dll (на сайте Microsoft есть merge-модули для включения библиотеки в MSI). В коде, использующем парсер, добавлял CoInitializeEx/CoUninitialize. В целом все устраивало, но портировать имеющийся код под тот же Linux невозможно, при создании нового потока, в котором используется парсер, нужно не забыть вызвать CoInitializeEx, если используется модель COINIT_APARTMENTTHREADED, ради работы с XML приходилось тащить в код включение windows.h.

Решил поискать альтернативу из числа свободных библиотек со следующими требованиями:
  • С++
  • полная поддержка Unicode
  • возможность чтения данных из XML в wchar_t, даже если документ сохранен в UTF-8
  • легкая, желательно развивающаяся, достаточно хорошо документированная
  • MIT-лицензия
  • большой плюс - поддержка XPath

Из числа найденных библиотек выделил RapidXml и pugixml. Обе распространяются под MIT-лицензией, обе содержат минимум файлов исходных кодов (в RapidXml код самого парсера находится в одном файле rapidxml.hpp), обе поддерживают Unicode, обе очень быстро обрабатывают XML, во многом за счет того, что не поддерживают валидацию.

Еще наверно стоит сказать, что RapidXml используется в Boost.PropertyTree.

Для моих нужд RapidXml не подошел тем, что хотя и поддерживает Unicode, но возвращает строки ровно в той кодировке, в которой их считал из файла. К тому же оказалось, что поддержка Unicode в реальности сводится к поддержке UTF-8 (например, файл с BOM UTF-16 не поддерживается). XPath не поддерживается вовсе.

Все то, чего нет в RapidXml и даже больше, я обнаружил в pugixml.

pugixml не только поддерживает UTF-8, UTF-16 и UTF-32, но еще и автоматически конвертирует кодировки и может отдавать строки в wchar_t. Для меня этот момент принципиальный, потому как внутри своего проекта я использую wchar_t, а сохраняю файлы в UTF-8. Парсер может автоматически определять кодировку документа по BOM (Byte Order Mark). При сохранении может перекодировать документ в другую кодировку и сохранять или не сохранять BOM.

pugixml поддерживает XPath 1.0, благодаря чему искать элементы проще, а код короче.

Документация для pugixml достаточна, чтобы быстро начать работу.

Есть еще масса таких мелочей, как загрузка XML из памяти или callback для сохранения документа. В общем, если вам нужно работать с XML - очень рекомендую pugixml!

No comments: