Вдогонку к моему вчерашнему выплеску ненависти к XML.
Долго думал над комментарием ув.тов.Зверька. Пришел к выводу, что это у меня такое же субъективное неприятие XML, как у многих программистов неприятие C++ ;)
Ну да, возникла когда-то давно на безрыбье корявенькая технология. По какому-то странному стечению обстоятельств стала доминирующей в своей области, проникла во много других областей, куда нужно и не нужно. Работа с ней требует внимательности и больших знаний, но дело спасают специально разработанные инструменты. Хорошо, когда без нее можно обойтись, но неприятно с ней бодаться, когда приходится ее использовать. Хотелось бы от нее избавиться, но никуда не денешься – она уже не убиваема. И внедряется в новые проекты потому, что она уже есть, ее много что поддерживает, есть опыт, собственные наработки и т.д. Да и, по большому счету, серьезных альтернатив-то у нее, не смотря ни на что, нет.
Правда же, все вышесказанное отлично подходит под C++? ;) Хотя я об XML. А мог бы и о Java ;)
PS. А все-таки мне бы для работы с XML данными в С++ хотелось бы иметь простой, легкий в освоении и бесплатный инструмент, который бы позволял писать как-то так:
/*
* Разбор XML-сообщений вида:
*
* <message>
* <report>
* <status date="...">OK</status>
* </report>
* </message>
*
* или
*
* <message>
* <report>
* <status errorCode="..." description="...">...</status>
* </report>
* </message>
*/
AutoPtr< Document > doc = parse_document_from_stream( message_stream );
element_proxy_t status =
root( *doc, EL_MESSAGE )
.single_mandatory_element( EL_REPORT )
.single_mandatory_element( EL_STATUS );
if( EL_STATUS_OK == status.text() )
handle_success( status.mandatory_attribute( EL_ATTR_DATE ) );
else
handle_failure(
status.text(),
status.mandatory_attribute< int >( EL_ATTR_ERROR_CODE ),
status.mandatory_attribute( EL_ATTR_ERROR_DESCRIPTION ) );
PPS. У меня есть маленькая просьба. Я знаю, что мой блог читают и не C++ программисты. Обращаюсь к ним: поделитесь, плз, ссылочками на хорошие описания разных способов работы с XML в других статически-типизированных языках (C#, Java, OCaml или F#). Какие-нибудь статьи, чтобы прочитать и просто составить мнение о том, что в мире делается. Чтобы узнать, до чего, так сказать, передовая мысль дошла ;)
Совсем недавно появилось в Boost, возможно, это тебе подойдет. Там есть парсинг из XML.
ОтветитьУдалитьhttp://www.boost.org/doc/libs/1_41_0/doc/html/property_tree.html
На вскидку, там такая же беда, как и у Poco::Utils::XMLConfiguration: пути к ключам/тегам приходится хардкодить в виде строк (парсинг которых выполняется при каждом обращении).
ОтветитьУдалитьТ.е. программиста вынуждают писать в стиле:
error_code = m.get<int>( "message.report.status.errorCode" );
error_desc = m.get( "message.report.status.errorDescription" );
Если человек захочет вынести имена тегов из кода в константы, то как ему это делать?
const std::string error_code_path( "message.report.status.errorCode" );
const std::string error_code_desc( "message.report.status.errorDescription" );
Или же:
#define MESSAGE "message"
#define REPORT "report"
#define STATUS "status"
#define DOT "."
const std::string error_code_path( MESSAGE DOT REPORT DOT STATUS DOT "errorCode" );
const std::string error_code_desc( MESSAGE DOT REPORT DOT STATUS DOT "errorDescription" );
Утрирую, конечно, но суть такая -- мне не нравится указание полных путей к значению. Имхо, это не правильно.
А вы не думали об использовании xslt? Для конкретной задачи не подойдёт идея дёргать из xslt преобразования функции на плюсах? Мы использовали xalan для целей преобразования xml с вычислениями на плюсах, всё в меру удобно.
ОтветитьУдалитьПонятно, что в вашей задаче само преобразование не нужно, но тем не менее.
>А вы не думали об использовании xslt?
ОтветитьУдалитьЧесно говоря, не думал. Имхо, это был бы какой-то слишком навороченный комбайн -- подключить XSLT, чтобы преобразовать XML в какой-то другой формат, затем разобрать этот формат... Через чур все это.
В моем случае лучше всего бы подошел XPath, но чтобы его использовать в С++ пришлось бы тянуть в проект libxml2. Проще оказалось сделать чуть больше телодвижений с помощью POCO.