[英]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 將換行符轉換為
在我看來,這是一個錯誤,因為僅包含空格(換行符、空格和制表符)的元素被視為文本元素。 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));
如此處所述:
“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.