簡體   English   中英

boost::property_tree XML 漂亮的打印

[英]boost::property_tree XML pretty printing

我正在使用 boost::property_tree 在我的應用程序中讀取和寫入 XML 配置文件。 但是當我寫文件時,output 看起來有點難看,文件中有很多空行。 問題是它也應該由人類編輯,所以我想獲得更好的 output。

作為例子,我寫了一個小測試程序:

#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>

除了手動通過 output 並刪除空行之外,有沒有辦法獲得更好的 output?

解決方案是將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;
}

該標志記錄在此處,但該庫的當前維護者 (Sebastien Redl) 很友好地回答並指出了它。

這個問題很老了,但最近我再次調查了你的問題,因為現在 property_tree 將換行符轉換為

&#10;    

在我看來,這是一個錯誤,因為僅包含空格(換行符、空格和制表符)的元素被視為文本元素。 trim_whitespace 只是一個創可貼,對 property_tree 中的所有空白進行規范化。

我在此處報告了該錯誤並附加了 a.diff 以修復 Boost 1.59 中的此行為,以防不使用trim_whitespace:https://svn.boost.org/trac/boost/ticket/11600

對於那些嘗試:

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

在 VisualStudio 2013 中使用 boost-1.60.0 進行編譯,您可能會得到:

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

“trim_whitespace”的設置在這里不是正確的答案。 如果您不能修剪數據項(在您閱讀時會發生),那么在讀取時修剪空白是沒有用的。

我認為這里出了什么問題,在: https://www.boost.org/doc/libs/1_81_0/boost/property_tree/detail/xml_parser_write.hpp

而不是:

            // Write data text, if present
            if (!pt.data().empty())
                write_xml_text(stream,
                    pt.template get_value<Str>(),
                    indent + 1, has_elements && want_pretty, settings);

應該有類似的東西:

            // Write data text, if not empty/white-space only
            auto d = pt.data();
            bool is_empty = d.erase(d.find_last_not_of(" \n\r\t")+1).empty();
            if (!is_empty)
                write_xml_text(stream,
                    pt.template get_value<Str>(),
                    indent + 1, has_elements && want_pretty, settings);

這似乎解決了 IMO 上面看到的“奇怪”行為——作者沒有添加空行或“僅空格”新行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM