boost :: property_tree XML красивая печать - PullRequest
29 голосов
/ 04 июля 2011

Я использую boost :: property_tree для чтения и записи файлов конфигурации XML в моем приложении. Но когда я пишу файл, вывод выглядит довольно уродливо с большим количеством пустых строк в файле. Проблема в том, что он должен быть отредактирован людьми, поэтому я хотел бы получить лучший результат.

В качестве примера я написал небольшую тестовую программу:

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>

int main( void )
{
    using boost::property_tree::ptree;
    ptree pt;

    // reading file.xml
    read_xml("file.xml", pt);

    // writing the unchanged ptree in file2.xml
    boost::property_tree::xml_writer_settings<char> settings('\t', 1);
    write_xml("file2.xml", pt, std::locale(), settings);

    return 0;
}

file.xml содержит:

<?xml version="1.0" ?>
<config>
    <net>
        <listenPort>10420</listenPort>
    </net>
</config>

после запуска программы file2.xml содержит:

<?xml version="1.0" encoding="utf-8"?>
<config>



    <net>



        <listenPort>10420</listenPort>
    </net>
</config>

Есть ли способ получить более качественный вывод, кроме ручного просмотра и удаления пустых строк?

Ответы [ 3 ]

41 голосов
/ 07 июля 2011

Решением было добавить флаг trim_whitespace к вызову read_xml:

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>

int main( void )
{
    // Create an empty property tree object
    using boost::property_tree::ptree;
    ptree pt;

    // reading file.xml
    read_xml("file.xml", pt, boost::property_tree::xml_parser::trim_whitespace );

    // writing the unchanged ptree in file2.xml
    boost::property_tree::xml_writer_settings<char> settings('\t', 1);
    write_xml("file2.xml", pt, std::locale(), settings);

    return 0;
}

Флаг задокументирован здесь , но текущий сопровождающий библиотеки (СебастьянРедл) был достаточно любезен, чтобы ответить и указать мне на это.

3 голосов
/ 03 сентября 2015

Этот вопрос довольно старый, но в последнее время я снова исследовал вашу проблему, потому что теперь стало намного хуже, когда property_tree переводит переводы строки в

&#10;    

На мой взгляд, это ошибка, потому что элементы, которые содержат только пробелы - символы новой строки, пробелы и табуляции, рассматриваются как текстовые элементы. trim_whitespace является только полосой и нормализует ВСЕ пробелы в property_tree.

Я сообщил об ошибке здесь и также добавил .diff, чтобы исправить это поведение в Boost 1.59 в случае, если trim_whitespace не используется: https://svn.boost.org/trac/boost/ticket/11600

2 голосов
/ 06 декабря 2016

Для тех, кто пытается:

boost::property_tree::xml_writer_settings<char> settings('\t', 1);

Компилируя с boost-1.60.0 в VisualStudio 2013, вы можете получить:

vmtknetworktest.cpp(259) : see reference to class template instantiation 'boost::property_tree::xml_parser::xml_writer_settings<char>' being compiled
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(38): error C2039: 'value_type' : is not a member of '`global namespace''
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(38): error C2146: syntax error : missing ';' before identifier 'Ch'
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(38): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(40): error C2061: syntax error : identifier 'Ch'
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(49): error C2146: syntax error : missing ';' before identifier 'indent_char'
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(49): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(50): error C2825: 'Str': must be a class or namespace when followed by '::'
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(50): error C2039: 'size_type' : is not a member of '`global namespace''
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(50): error C2146: syntax error : missing ';' before identifier 'indent_count'
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(50): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
vmtknetworktest.cpp(259): error C2661: 'boost::property_tree::xml_parser::xml_writer_settings<char>::xml_writer_settings' : no overloaded function takes 3 arguments

Тогда в конечном итоге здесь:

https://svn.boost.org/trac/boost/ticket/10272

Решение для работы - использовать std :: string в шаблоне.

pt::write_xml(file_name, params, std::locale(), pt::xml_writer_make_settings< std::string >(' ', 4));

как описано здесь:

https://stackoverflow.com/a/35043551/7170333

...