Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > boost::property_tree


Автор: HellStranger 30.7.2010, 11:08
Всем доброго времени суток. Ещё один вопрос по boost::proprty_tree.

Есть XML

Код

<?xml version="1.0" encoding="windows-1251" ?> 
- <EroChatClient_Config>
  <Windows_Media_Server_Address>BOOK3G</Windows_Media_Server_Address> 
  <Windows_Media_Server_Port>80</Windows_Media_Server_Port> 
  <HTTP_Server>www.blablabla.ru</HTTP_Server> 
  <HTTP_Text_Request>/testxml.php</HTTP_Text_Request> 
- <Commands>
- <command name="authorisation">
- <request>
  <text_request>XML/XML_Authorisation_Request.xml</text_request> 
  <property>Login</property> 
  <property>Password</property> 
  </request>
- <response>
  <property>model_id</property> 
  <property>error_code</property> 
  </response>
  </command>


Далее идут одни команды в указанном формате и потом собсвенно XML заканчивается. Внимание вопрос:

Код

BOOST_FOREACH(const boost::property_tree::ptree::value_type& first_level_child, pTreeConfig->get_child("EroChatClient_Config.Commands"))


Этот код работает, реально получаю поддерево первой команды. Но как мне потом получить чилдренов узла command?

При попытке тупо:
(понимаю, бред. но уже всё перепробовал)
Код

BOOST_FOREACH(const boost::property_tree::ptree::value_type& first_level_child, pTreeConfig->get_child("EroChatClient_Config.Commands.command"))


или

Код

BOOST_FOREACH(const boost::property_tree::ptree::value_type& first_level_child, pTreeConfig->get_child("command"))


сваливается в exception типа boost::property_tree::ptree_bad_path. Не находит соответствующего узла... 

И ещё вопросец:

Код

std::string xmlFilename = Second_Level_Property.get_value<std::string>(second_level_child.first);


Почему в xmlFilename записывается не "XML/XML_Authorisation_Request.xml", а "\10XML/XML_Authorisation_Request.xml\10", возврат карретки откуда берётся, в xml его не было...

Поможите, чем можите в общем. smile

Автор: HellStranger 3.8.2010, 14:07
В общем пролблема решилась следующим образом:


Код

std::string sNodeNameMainLevel = "EroChatClient_Config.Commands";

// pTreeConfig - объект boost::property_tree::ptree, представляющий весь на xml.

BOOST_FOREACH(const BOOSTPTree::value_type& first_level_child, pTreeConfig->get_child(sNodeNameMainLevel))
{
// node element processing
...
    std::string sNodeNameLevel1 = sNodeNameMainLevel + "." + first_level_child.first;

    BOOST_FOREACH(const BOOSTPTree::value_type& second_level_child, pTreeConfig->get_child(sNodeNameLevel1))
    {
// node element processing
...
        std::string sNodeNameLevel2 = sNodeNameLevel1 + "." + second_level_child.first;
        BOOST_FOREACH(const BOOSTPTree::value_type& third_level_child, pTreeConfig->get_child(sNodeNameLevel2))
        {
// node element processing
...
        }
    }
}


Правда для этого пришлось немного видоизменить xml:

Код

<?xml version="1.0" encoding="windows-1251" ?> 
- <EroChatClient_Config>
  <Windows_Media_Server_Address>BOOK3G</Windows_Media_Server_Address> 
  <Windows_Media_Server_Port>80</Windows_Media_Server_Port> 
  <HTTP_Server>www.partners2.motvet.ru</HTTP_Server> 
  <HTTP_Text_Request>/testxml.php</HTTP_Text_Request> 
- <Commands>
- <command1 name="authorization">
- <request>
  <text_request>XML/XML_Authorisation_Request.xml</text_request> 
  <property>Login</property> 
  <property>Password</property> 
  </request>
- <response>
  <property>model_id</property> 
  <property>error_code</property> 
  </response>
  </command1>
- <command2 name="state_online">
- <request>
  <text_request>XML_StateOnline_Request.xml</text_request> 
  <property /> 
  </request>
- <response>
  <property /> 
  </response>
  </command2>


Вообще бустовский xml-парсер, ИМХО вещь глупая и глючная до ужаса. Подходит только для того, чтобы парсить примитв как в бустовских туториалах по property_tree. Для xml, чуть сложнее примитива, лучше юзать .NET-решения: оборачивать их в неуправляемую .dll и радоваться жизни! Мне пришлось заюзать, так как уже была привязка к бусту: Их HTTP-клиента заюзал. В общем пожалел стопятьсот раз...

Автор: bsa 3.8.2010, 17:52
Цитата(HellStranger @  3.8.2010,  15:07 Найти цитируемый пост)
.NET-решения: оборачивать их в неуправляемую .dll и радоваться жизни!

сомнительное удовольствие.
Уж лучше тогда воспользуйся парсером http://rapidxml.sourceforge.net/manual.html, который используется property_tree для разбора xml. Имхо, property_tree не совсем для XML предназначено.

Автор: HellStranger 4.8.2010, 11:53
Цитата(bsa @  3.8.2010,  17:52 Найти цитируемый пост)
сомнительное удовольствие.


Поверьте, вполне даже сексуально получается... На RSDN тема есть с примерами обёртки класса Regex. Для пользовательских приложений тормоза .NET не критичны, даже полезны. smile В принципе я бы так и сделал, если бы в .NET был класс, устраивающий меня в качестве HTTP-клиента, но... его не оказалось... Хотя, может, плохо искал... А тянуть за собой WinHTTP, ну об этом ниже сказано...

Цитата(bsa @  3.8.2010,  17:52 Найти цитируемый пост)
Уж лучше тогда воспользуйся парсером rapidxml, который используется property_tree для разбора xml.


Да xml-парсеров предостаточно. Я не хочу здесь обсуждать, какой лучше, какой хуже. Не хотелось за собой таксать сотню open source проектов: визуальная часть- wx, HTTP- boost, xml- тот же самый rapidxml. И так далее. Можно было всё взять из wx, но про xml у Смарта написано, что вещь сырая, будет дорабатываться и без обратной совместимости, с HTTP в wx тоже не всё безоблачно. Пришлось выбрать boost, теперь понял, что выбор был совершенно не правильный, но уже поздно: вроде с горем пополам все проблемы пофиксил...

Цитата(bsa @  3.8.2010,  17:52 Найти цитируемый пост)
Имхо, property_tree не совсем для XML предназначено.


ИМХО, область его применения к xml ограничивается примерами в туториале. smile Но зато теперь я могу это утверждать, не ссылаясь, на кого-то, а попробовав сам, и всё-таки решив, то, что было нужно...

Автор: apexmi 23.10.2010, 06:33
Ребят! подскажите, пож-та. Если я хочу парсить xml не из конфигурационного файла, то как мне его запихать в property tree? Есть функция для считывания xml из фаqла. А как быть, если я хочу распарсить какой нить текстовый буфер. Скажем я его получил по tcp/ip. Есть функция для парсинга из потока. Но как мне текст запихать в поток так и не могу понять.

Автор: borisbn 23.10.2010, 10:22
Цитата(HellStranger @  4.8.2010,  11:53 Найти цитируемый пост)
визуальная часть- wx, HTTP- boost, xml- тот же самый rapidxml. И так далее.

Qt - не решение ?
Цитата(apexmi @  23.10.2010,  06:33 Найти цитируемый пост)
А как быть, если я хочу распарсить какой нить текстовый буфер

Код

QDomDocument doc;
doc.setContent( текстовая строка );


Автор: boostcoder 17.12.2010, 11:27
Цитата(apexmi @  23.10.2010,  06:33 Найти цитируемый пост)
Если я хочу парсить xml не из конфигурационного файла, то как мне его запихать в property tree?

искал доку по property_tree, и наткнулся на этот пост.
вот так:
Код

const char* buf = ...
std::istringstream is(buf);
... ::read_xml(is, ...);


Добавлено через 5 минут и 6 секунд
а вот и небольшой туториал: http://www.devexp.ru/2010/02/chtenie-nastroek-prilozheniya/
конечно не то что я искал, но может кому сгодится.

Автор: xvr 20.12.2010, 15:02
Цитата(HellStranger @  4.8.2010,  11:53 Найти цитируемый пост)
Поверьте, вполне даже сексуально получается...
Верю, весьма сексуально  smile Но за сексуальностью обычно в другое место ходят  smile 
Цитата(HellStranger @  4.8.2010,  11:53 Найти цитируемый пост)
Не хотелось за собой таксать сотню open source проектов
Тогда пользуйте MSXML через COM - для Win родное, .NET не требует, стандартный DOM интерфейс, чистый С++, что еще надо?


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)