Использование Boost для чтения и записи XML-файлов
есть ли хороший способ (и простой способ тоже) с помощью Boost для чтения и записи XML-файлов?
Я не могу найти простой пример для чтения XML-файлов с помощью Boost. Можете ли вы указать мне простой пример, который использует Boost для чтения и записи XML-файлов?
Если не Boost, есть ли хорошая и простая библиотека для чтения и записи XML-файлов, которые вы можете порекомендовать? (это должна быть библиотека C++)
15 ответов:
вы должны попробовать pugixmlлегкий, простой и быстрый XML-парсер для C++
самое приятное в pugixml-это XPath поддержка, которой не хватает TinyXML и RapidXML.
цитируя автора RapidXML "я хотел бы поблагодарить Арсения Капулкина за его работу над pugixml, которая была вдохновением для этого проекта" и "5% - 30% быстрее, чем pugixml, самый быстрый XML-парсер, который я знаю", он протестировал против версии 0.3 pugixml, который недавно достиг версии 0.42.
вот выдержка из документации pugixml:
основные характеристики:
- низкое потребление памяти и фрагментация (победа над pugxml составляет ~1,3 раза, TinyXML - ~2,5 раза, Xerces (DOM) - ~4,3 раза 1). Точные цифры можно увидеть в сравнении с существующим разделом парсеров.
- чрезвычайно высокая скорость разбора (победа над pugxml составляет ~6 раз, TinyXML - ~10 раз, Xerces-DOM - ~17.6 раза 1
- чрезвычайно высокая скорость синтаксического анализа (ну, я повторяюсь, но это так быстро, что он превосходит Expat в 2,8 раза на тестовом XML) 2
- более или менее стандартно-совместимый (он будет правильно анализировать любой стандартно-совместимый файл, за исключением проблем, связанных с DTD)
- в значительной степени ошибка-невежественный (он не будет задыхаться от чего-то вроде вас и меня, как экспат будет; он будет анализировать файлы с данными в неправильной кодировке; и так о)
- чистый интерфейс (сильно переделанный pugxml один)
- более или менее осведомленное о Unicode (на самом деле, предполагается кодировка UTF-8 входных данных, хотя это будет непросто работать с ANSI - не UTF-16 сейчас (см. будущей работы), с помощью вспомогательной функции преобразования кодировок (UTF-8 кодировка UTF-16/32 (что является значением по умолчанию для std::wstring, которая & тип wchar_t))
- полностью стандартный совместимый код C++ (одобренный строгим режимом Comeau); библиотека является мультиплатформенной (см. ссылку для список платформ)
- высокая гибкость. Вы можете управлять многими аспектами синтаксического анализа файлов и построения дерева DOM с помощью параметров синтаксического анализа.
хорошо, вы можете спросить - в чем подвох? Все так мило-это маленькое, быстрое, надежное, чистое решение для разбора XML. Чего не хватает? Хорошо, мы честные разработчики-так вот список misfeature:
- потребление памяти. Он бьет каждый парсер на основе DOM, о котором я знаю, но когда приходит SAX parser, есть без шансов. Вы не можете обработать 2 Гб XML - файла с менее чем 4 Гб памяти-и сделать это быстро. Хотя pugixml ведет себя лучше, чем все другие DOM-парсер, так что если вы застряли с DOM, это не проблема.
- потребление памяти. Ладно, я повторяюсь. Снова. Когда другие Парсеры позволят вам предоставить XML-файл в постоянное хранилище (или даже в качестве области отображения памяти), pugixml не будет. Так что вам придется скопировать все данные в постоянном хранилище. Более того, он должен сохраняйтесь в течение жизни парсера (причины этого и многое другое о жизнях написано ниже). Опять же, если вы в порядке с DOM - это не должно быть проблемой, потому что общее потребление памяти меньше (ну, хотя вам понадобится непрерывный кусок памяти, что может быть проблемой).
- отсутствие проверки, обработка DTD, пространства имен XML, правильная обработка кодировки. Если вам это нужно-возьмите MSXML или XercesC или что-нибудь в этом роде.
TinyXML - это, вероятно, хороший выбор. Что касается Boost:
есть Property_Tree библиотека Boost Репозиторий. Это было принято, но поддержка, кажется, не хватает на данный момент (EDIT:Property_Tree теперь является частью Boost начиная с версии 1.41, читать документация относительно его функциональности XML).
Даниэль Нуффер реализовал синтаксический анализатор XML для повышения Духа.
Boost использует RapidXML как описано в глава XML Parser страницы Как заполнить дерево свойств:
к сожалению, нет XML парсер в Boost на момент написания этой статьи. Поэтому библиотека содержит быстрый и крошечный RapidXML парсер (в настоящее время версия 1.13) для обеспечения синтаксического анализа XML поддержка. RapidXML не полностью поддерживает стандарт XML; он не способен анализировать DTDs и поэтому не может этого сделать полная замена сущности.
пожалуйста, обратитесь к XML boost tutorial.
как ОП хочет "простой способ использовать boost для чтения и записи xml-файлов" я приведу ниже очень простой пример:
<main> <owner>Matt</owner> <cats> <cat>Scarface Max</cat> <cat>Moose</cat> <cat>Snowball</cat> <cat>Powerball</cat> <cat>Miss Pudge</cat> <cat>Needlenose</cat> <cat>Sweety Pie</cat> <cat>Peacey</cat> <cat>Funnyface</cat> </cats> </main>(Кошачьи имена от Мэтт Махоуни Домашняя страница)
соответствующая структура в C++:
struct Catowner { std::string owner; std::set<std::string> cats; };
read_xml()использование:#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/xml_parser.hpp> Catowner load(const std::string &file) { boost::property_tree::ptree pt; read_xml(file, pt); Catowner co; co.owner = pt.get<std::string>("main.owner"); BOOST_FOREACH( boost::property_tree::ptree::value_type &v, pt.get_child("main.cats")) co.cats.insert(v.second.data()); return co; }
write_xml()использование:void save(const Catowner &co, const std::string &file) { boost::property_tree::ptree pt; pt.put("main.owner", co.owner); BOOST_FOREACH( const std::string &name, co.cats) pt.add("main.cats.cat", name); write_xml(file, pt); }
Ну нет конкретной библиотеки в boost для синтаксического анализа XML, но есть много альтернатив, вот пара: libxml, Xerces, экспат
конечно, вы можете использовать некоторые из других библиотек в boost, чтобы помочь вам в создании своей собственной библиотеки, но это, вероятно, будет довольно сложно.
и вот это Целая статья по теме от IBM.
Boost не предоставляет atm-анализатор XML.
Poco XML (часть Poco c++ libs) это хорошо и просто.
похоже, что boost serialization может читать и записывать в архивы в XML, если этого достаточно для ваших целей.
посмотри арабики
Если вы ищете только функциональность DOM, есть некоторые предложения уже в этой теме. Я лично, вероятно, не стал бы беспокоиться о библиотеке, не имеющей поддержки XPath, и в C++ использовал бы Qt. Есть также TinyXPath, и Арабика утверждает, что имеет поддержку XPath, но я ничего не могу сказать об этом.
из моего опыта, скрывающегося в списке рассылки Boost, кажется, что каждый раз, когда XML появляется в качестве темы, он отвлекается на обсуждение Unicode. Однако, поскольку прямо сейчас существует потенциальная библиотека Unicode, я не думаю, что это займет слишком много времени для появления библиотеки XML.
в то же время, я тоже использую TinyXML.
интересная ссылка о RapidXML. Я посмотрю на это.
предупреждение. Я люблю RapidXML, но у него есть очень неприятная ошибка при разборе UTF16. Некоторые допустимые значения приводят к сбою.
Я хотел бы рекомендовать pugixml - но ему не хватает поддержки пространства имен, которая, как я знаю, вызовет у меня проблемы.
существует GSoC предложил работу по улучшению существующего предложения Boost.XML:https://github.com/stefanseefeld/boost.xml но как Анджей предложил форсировать.PropertyTree хорошо подходит для этой задачи. Естественно, в зависимости от размера xml и необходимой поддержки проверки.
есть также библиотека, которая недавно была предложена в списке рассылки Boost : http://www.codesynthesis.com/projects/libstudxml/doc/intro.xhtml
Как насчет повышения.дух?
здесь, они показывают " мини XML" парсер
<?xml version="1.0"?> <Settings> <GroupA> <One>4</One> <Two>7</Two> <Three>9</Three> </GroupA> <GroupA> <One>454</One> <Two>47</Two> <Three>29</Three> </GroupA> <GroupB> <A>String A</A> <B>String B</B> </GroupB> </Settings>существует простой способ чтения XML с помощью BOOST. Этот пример с std:: wstring based:
#include <string> #include <boost/property_tree/xml_parser.hpp> #include <boost/property_tree/ptree.hpp> #include <boost/foreach.hpp> bool CMyClass::ReadXML(std::wstring &full_path) { using boost::property_tree::wptree; // Populate tree structure pt: wptree pt; std::wstringstream ss; ss << load_text_file(full_path); // See below for ref. read_xml(ss, pt); // Traverse pt: BOOST_FOREACH(wptree::value_type const& v, pt.get_child(L"Settings")) { if (v.first == L"GroupA") { unsigned int n1 = v.second.get<unsigned int>(L"One"); unsigned int n2 = v.second.get<unsigned int>(L"Two"); unsigned int n3= v.second.get<unsigned int>(L"Three"); } else if (v.first == L"GroupB") { std::wstring wstrA = v.second.get<std::wstring>(L"A"); std::wstring wstrB = v.second.get<std::wstring>(L"B"); } }; }читать атрибуты просто немного сложнее.
-
просто для справки:
std::wstring load_text_file(std::wstring &full_path) { std::wifstream wif(full_path); wif.seekg(0, std::ios::end); buffer.resize(wif.tellg()); wif.seekg(0); wif.read(buffer.data(), buffer.size()); return buffer; }
Comments