【转载】boost::property_tree
Boost.PropertyTree 应该是 Boost 1.41.0 开始正式加入 Boost 版本的。目前 ( 2010/02/28 ) 能下到的最新版本是 1.42.0。
- 主要作用/应用场合
Boost.PropertyTree 提供了一种结构化的数据存储容器。并且提供了一系列的解释器可以将内存中的结构与具体格式相互转换 (比如: INI, XML, JSON )。
至少可以用在:
- 进程间通讯或者跨语言的进程间的通讯
- 一些配置文件的存取
- 网络通讯协议的格式
- 基本用法
基本用法有 2 种场景。第一种是从 Property Tree存储到具体格式。第二种是从具体格式解析到具体的 Property Tree。其他还有一些 Property Tree 操作的方法,比如:遍历、搜索等方法。
以下这个 Sample 就是基本用法的测试:
先把 数据存储到 datum 中,随后输出 相应的 XML 和 JSON 到 std::cout 上。最后再从 JSON Stream 中解析输入到 ptParse 中获得相应 的数据。
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <string>
#include <locale>
#include "boost/property_tree/ptree.hpp"
#include "boost/property_tree/json_parser.hpp"
#include "boost/property_tree/xml_parser.hpp"
int main(int argc, char **argv)
{
/* The data format
* <root>
* <num>1</num>
* <str>Test</str>
* </root>
*/
try
{
/* create the property tree */
boost::property_tree::ptree datum;
datum.put("root.num", 100);
datum.put("root.str", "string");
/* output XML string */
std::ostringstream xmlOutputStream;
boost::property_tree::xml_parser::write_xml(xmlOutputStream,
datum);
std::cout << "XML format:" << std::endl;
std::cout << xmlOutputStream.str() << std::endl;
/* output JSON string */
std::ostringstream jsonOutputStream;
boost::property_tree::json_parser::write_json(jsonOutputStream,
datum);
std::cout << "JSON format:" << std::endl;
std::cout << jsonOutputStream.str() << std::endl;
/* read datum from JSON stream */
boost::property_tree::ptree ptParse;
std::istringstream jsonIStream;
jsonIStream.str(jsonOutputStream.str());
boost::property_tree::json_parser::read_json(jsonIStream,
ptParse);
int num = ptParse.get<int>("root.num");
std::string strVal = ptParse.get<std::string>("root.str");
std::cout << "Num=" << std::dec << num
<< " Str=" << strVal << std::endl << std::endl;
}
catch (...)
{
printf("create boost::property_tree::ptree failed\n");
}
return 0;
}
- 关于字符集
Boost 目前是支持 UTF8 的,但是不能直接用 Unicode。所以,如果要存储宽字符就有点麻烦需要用到 Boost 提供的 utf8_codecvt_facet 做转换。
下面就是一个存储 wchar_t 的 Sample:
和之前的其实差不多,有 2 点主要不同。一是用了 wptree 替换了 ptree。二是增加了 utf8_codecvt_facet 在相应的 Stream 里做转换。
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <string>
#include <locale>
#include "boost/property_tree/ptree.hpp"
#include "boost/property_tree/json_parser.hpp"
#include "boost/property_tree/xml_parser.hpp"
#include "boost/program_options/detail/convert.hpp"
#include "boost/program_options/detail/utf8_codecvt_facet.hpp"
int main(int argc, char **argv)
{
/* The data format
* <root>
* <num>1</num>
* <str>Test</str>
* </root>
*/
/* test UTF-8 format */
try
{
/* create boost utf8 codecvt */
std::locale oldLocale;
std::locale utf8Locale(oldLocale,
new boost::program_options::detail::utf8_codecvt_facet());
std::wcout.imbue(utf8Locale);
/* create the wptree for save the UTF-8 data */
boost::property_tree::wptree datum;
datum.put(L"root.num", 100);
datum.put(L"root.str", L"wstring");
/* output XML string */
std::wostringstream xmlOutputStream;
xmlOutputStream.imbue(utf8Locale);
boost::property_tree::xml_parser::write_xml(xmlOutputStream,
datum);
std::wcout << L"XML format:" << std::endl;
std::wcout << xmlOutputStream.str() << std::endl;
/* output JSON string */
std::wostringstream jsonOutputStream;
jsonOutputStream.imbue(utf8Locale);
boost::property_tree::json_parser::write_json(jsonOutputStream,
datum);
std::wcout << L"JSON format:" << std::endl;
std::wcout << jsonOutputStream.str() << std::endl;
/* read datum from JSON stream */
boost::property_tree::wptree wptParse;
std::wistringstream jsonIStream;
jsonIStream.imbue(utf8Locale);
jsonIStream.str(jsonOutputStream.str());
boost::property_tree::json_parser::read_json(jsonIStream,
wptParse);
int num = wptParse.get<int>(L"root.num");
std::wstring wstrVal = wptParse.get<std::wstring>(L"root.str");
std::wcout << L"Num=" << std::dec << num
<< L" Str=" << wstrVal << std::endl << std::endl;
}
catch (...)
{
printf("create boost::property_tree::wptree failed\n");
}
return 0;
}
- 附录
- 以上的测试程序,在 Boost 1.42.0 和 MS VS 2008 上测试过。这里是打包文件PTreeTest
- 在 Boot.org 上能找到更多的 PropertyTree 的操作。PropertyTree 在 Boost 1.41.0 版本的手册。最好去看新版本的如果以后更新的话。
- Boot.PropertyTree 用的 XML 解析器是 RapidXML 。是一个基于模板设计的 XML 操作库 ,有非常好的性能(据说)。
转自:http://notes.xj-labs.net/?p=52
utf8_codecvt_facet
template<
typename InternType = wchar_t,
typename ExternType = char
> utf8_codecvt_facet
Rationale
UTF-8 is a method of encoding Unicode text in environments where where data is stored as 8-bit characters and some ascii characters are considered special (i.e. Unix filesystem filenames) and tend to appear more commonly than other characters. While UTF-8 is convenient and efficient for storing data on filesystems, it was not meant to be manipulated in memory by applications. While some applications (such as Unix's 'cat') can simply ignore the encoding of data, others should convert from UTF-8 to UCS-4 (the more canonical representation of Unicode) on reading from file, and reversing the process on writing out to file.
The C++ Standard IOStreams provides the std::codecvt facet to handle specifically these cases. On reading from or writing to a file, the std::basic_filebuf can call out to the codecvt facet to convert data representations from external format (ie. UTF-8) to internal format (ie. UCS-4) and vice-versa. utf8_codecvt_facet is a specialization of std::codecvt specifically designed to handle the case of translating between UTF-8 and UCS-4.
Template Parameters
| Parameter | Description | Default |
|---|---|---|
| InternType | The internal type used to represent UCS-4 characters. | wchar_t |
| ExternType | The external type used to represent UTF-8 octets. | char_t |
Requirements
utf8_codecvt_facet defaults to using char as it's external data type and wchar_t as it's internal datatype, but on some architectures wchar_t is not large enough to hold UCS-4 characters. In order to use another internal type.You must also specialize std::codecvt to handle your internal and external types. (std::codecvt<char,wchar_t,std::mbstate_t> is required to be supplied by any standard-conforming compiler).
Example Use
The following is a simple example of using this facet:
//...
// My encoding type
typedef wchar_t ucs4_t;
std::locale old_locale;
std::locale utf8_locale(old_locale,new utf8_codecvt_facet<ucs4_t>);
// Set a New global locale
std::locale::global(utf8_locale);
// Send the UCS-4 data out, converting to UTF-8
{
std::wofstream ofs("data.ucd");
ofs.imbue(utf8_locale);
std::copy(ucs4_data.begin(),ucs4_data.end(),
std::ostream_iterator<ucs4_t,ucs4_t>(ofs));
}
// Read the UTF-8 data back in, converting to UCS-4 on the way in
std::vector<ucs4_t> from_file;
{
std::wifstream ifs("data.ucd");
ifs.imbue(utf8_locale);
ucs4_t item = 0;
while (ifs >> item) from_file.push_back(item);
}
//...
History
This code was originally written as an iterator adaptor over containers for use with UTF-8 encoded strings in memory. Dietmar Kuehl suggested that it would be better provided as a codecvt facet.
Resources
- Unicode Homepage
- Standard C++ IOStreams and Locales
- The C++ Programming Language Special Edition, Appendix D.
浙公网安备 33010602011771号