Кое-кто слышал о библиотеке RapidXML — это single-header C++ XML парсер. Очень быстрый, довольно удобный, с некоторыми ограничениями на входной XML.
Мне не хватало в нем поддержки XML Namespaces и я её добавил.
RapidXML NS на GitHub.
Затраты памяти выросли незначительно. Затраты времени зависят от конкретного XML, но, думаю, тоже терпимо.
Замеры на файле не содержащем объявлений пространств имен:
rapidxml:
3.5 cycles/char mode=fastest
4.1 cycles/char mode=default
rapidxml_ns:
3.5 cycles/char mode=fastest
4.8 cycles/char mode=default
Первый результат — оригинальный RapidXML, третий — RapidXML NS в режиме без XML namespaces, т. е. они и должны совпадать.
17% базовый прирост времени. Любой другой парсер с поддержкой XML Namespaces, думаю, будет иметь совсем другой порядок использования CPU.
Ах да, лицензия свободная — Boost или MIT.
Здравствуйте, OlegMax, Вы писали:
OM>Кое-кто слышал о библиотеке RapidXML — это single-header C++ XML парсер. Очень быстрый, довольно удобный, с некоторыми ограничениями на входной XML.
Эх, вот не хватает подобным парсерам какой нибудь
такой штуки для лаконичности интерфейса.
Здравствуйте, sokel, Вы писали:
S>Эх, вот не хватает подобным парсерам какой нибудь такой штуки для лаконичности интерфейса.
Например Boost.Range:
boost::iterator_range<const char *> r = boost::as_literal(node->name());
Здравствуйте, OlegMax, Вы писали:
OM>Например Boost.Range:
OM>OM>boost::iterator_range<const char *> r = boost::as_literal(node->name());
OM>
Не совсем, null-terminated строки получаются за счёт записи нулей непосредственно в исходник XML, что как то не очень красиво для парсера. Просто чтобы сразу работать с не null-terminated строками в режиме parse_no_destructive.
Что собственно от строчек этих надо — сохранить, сравнить, отформатировать куда то. string_ref можно запросто конвертировать туда-сюда в любой тип строк, compare есть.
Можно использовать map cо string_ref в качестве ключа, например для диспетчеризации какой то по имени XML элемента. Хотя тут можно и дальше пойти, в ассоциативных контейнерах пригодились бы функции поиска по ключу отличному от хранимого, что то типа шаблонного find(custom_key, custom_compare). Компаратор string-string_ref простецкий, инвариантен относительно типов, нарисовал и вперед — string_map.find(node.name(), string_ref_compare()).
Здравствуйте, OlegMax, Вы писали:
OM>Например Boost.Range:
OM>OM>boost::iterator_range<const char *> r = boost::as_literal(node->name());
OM>
Ну собственно в boost то как раз и
string_ref есть. Просто класс то простой, будь он в стандарте, удобней было бы создавать интерфейсы, не привязанные к конкретным типам строк, — просто просишь на вход string_ref, позволяя при этом использовать хоть литералы, хоть std::string, да хоть даже любой пользовательский тип строки, имеющий оператор приведения к string_ref.