boost.property_tree解析xml的帮助类以及中文解析问题的解决

转载 2015年11月20日 11:55:02

boost.property_tree可以用来解析xml和json文件,我主要用它来解析xml文件,它内部封装了号称最快的xml解析器rapid_xml,其解析效率还是很好的。但是在使用过程中却发现各种不好用,归纳一下不好用的地方有这些:

获取不存在的节点时就抛出异常 获取属性值时,要排除属性和注释节点,如果没注意这一点就会抛出异常,让人摸不着头脑。 内存模型有点怪。 默认不支持中文的解析。解析中文会乱码。

ptree获取子节点

  获取子节点接口原型为get_child(node_path),这个node_path从当前路径开始的全路径,父路径和子路径之间通过“.”连接,如“root.sub.child”。需要注意的是get_child获取的是第一个子节点,如果我们要获取子节点列表,则要用路径“root.sub”,这个路径可以获取child的列表。如果获取节点的路径不存在则会抛出异常,这时,如果不希望抛出异常则可以用get_xxx_optional接口,该接口返回一个optional<T>的结果出来,由外面判断是否获取到结果了。

1.//ptree的optional接口
2.auto item = root.get_child_optional('Root.Scenes');

  该接口返回的是一个optional<ptree>,外面还要判断该节点是否存在,optional对象通过bool操作符来判断该对象是否是无效值,通过指针访问 

符'*'来访问该对象的实际内容。建议用optional接口访问xml节点。

1.//ptree的optional接口
2.auto item = root.get_child_optional('Root.Scenes');
3.if(item)
4.cout<<'该节点存在'<<endl;

ptree的内存模型

  ptree维护了一个pair<string, ptree>的子节点列表,first指向的是该节点的TagName,second指向的才是ptree节点,因此在遍历ptree子节点时要注意迭代器的含义。

1.for (auto& data : root)
2.{
3.for (auto& item : data.second) //列表元素为pair<string, ptree>,要用second继续遍历
4.{
5.cout<<item.first<<endl;
6.}
7.}

  需要注意的是ptree.first可能是属性('<xmlattr>')也可能是注释('<xmlcomment>'),只有非注释类型的节点才能使用获取属性值、子节点等常用接口。

ptree获取属性值

  通过get<T>(attr_name)可以获取属性的值,如果想获取属性的整形值的话,可以用get<int>('Id'),返回一个整数值。有一点要注意如果ptree.first为'<xmlcomment>'时,是没有属性值的,可以通过data()来获取注释内容。如果这个ptree.first不为<xmlattr>时需要在属性名称前面加'<xmlcomment>.',即get<int>('<xmlcomment>.Id')才能正确获取属性值。可以看到获取属性值还是比较繁琐的,在后面要介绍的帮助类中可以简化属性值的获取。如果要获取节点的值则用get_value()接口,该接口用来获取节点的值,如节点:<Field>2</Field>通过get_value()就可以获取值'2'。

解析中文的问题

  ptree只能解析窄字符的xml文件,如果xml文件中含有unicode如中文字符,解析出来就是乱码。解析unicode要用wptree,该类的接口均支持宽字符并且接口和ptree保持一致。要支持中文解析仅仅wptree还不够,还需要一个unicode转换器的帮助,该转换器可以实现宽字符和窄字符的转换,宽窄的互相转换函数有很多实现,不过c++11中有更简单统一的方式实现款窄字符的转换。

c++11中宽窄字符的转换:

1.std::wstring_convert<std::codecvt<wchar_t,char,std::mbstate_t>> conv
2. 
3.(newstd::codecvt<wchar_t,char,std::mbstate_t>('CHS'));
4.//宽字符转为窄字符
5.string str = conv.to_bytes(L'你好');
6.//窄字符转为宽字符
7.string wstr = conv.from_bytes(str);

  boost.property_tree在解析含中文的xml文件时,需要先将该文件转换一下。

  boost解决方法:

01.#include 'boost/program_options/detail/utf8_codecvt_facet.hpp'
02.void ParseChn()
03.{
04.std::wifstream f(fileName);
05.std::locale utf8Locale(std::locale(), new boost::program_options::detail::utf8_codecvt_facet());
06.f.imbue(utf8Locale); //先转换一下
07. 
08.//用wptree去解析
09.property_tree::wptree ptree;
10.property_tree::read_xml(f, ptree);   
11.}

  这种方法有个缺点就是要引入boost的libboost_program_options库,该库有二十多M,仅仅是为了解决一个中文问题,却要搞得这么麻烦,有点得不偿失。好在c++11提供更简单的方式,用c++11可以这样:

01.void Init(const wstring& fileName, wptree& ptree)
02.{
03.std::wifstream f(fileName);
04.std::locale utf8Locale(std::locale(), new std::codecvt_utf8<wchar_t>);
05.f.imbue(utf8Locale); //先转换一下
06. 
07.//用wptree去解析
08.property_tree::read_xml(f, ptree);
09.}

  用c++11就不需要再引入boost的libboost_program_options库了,很简单。

boost的property_tree组件

stl中对线性表有充分的实现,无论是vector还是list都是典型的线性表,即便是set和map,尽管实现上采用了诸如红黑树之类的树形结构,但那仅仅是为了快速检索的需要,从语义上来说它们依旧是线性表...
  • oowgsoo
  • oowgsoo
  • 2014年12月29日 21:45
  • 12336

boost::property_tree 基本用法

最近在开发C++时需要解析和设置配置文件XML,用了boost::property_tree ,看了相关资料并做了一下小小的总结: 1.读取单个值 XML: zhan...
  • baidu_34788529
  • baidu_34788529
  • 2016年04月25日 21:17
  • 294

用boost中的property_tree实现配置文件

property_tree是专为配置文件而写,支持xml,ini和json格式文件 ini比较简单,适合简单的配置,通常可能需要保存数组,这时xml是个不错的选择。 使用property_...
  • fireroll
  • fireroll
  • 2015年12月17日 14:19
  • 324

boost::property_tree

boost::property_tree 的解析xml模块是基于rapidXml的, 以下是两个例子: 例子1:  #include #include #include #include...
  • kamaliang
  • kamaliang
  • 2011年11月02日 17:49
  • 13628

boost.property_tree使用示例

下面是一个使用boost.property_tree来解析XML/INI文件的简单示例。 使用boost.property_tree来作为配置文件的解析工具非常合适. #include #inclu...
  • wzq9706
  • wzq9706
  • 2011年05月10日 14:06
  • 3540

解决使用Boost的ptree输出json中文乱码的问题

本文所使用的boost为1.55版本。 使用boost的ptree输出json的时候,中文会被转换为\uxxxx的utf8编码形式,json的标准中对于中文是转换为\uxxxx的utf16编码形...
  • bjrxyz
  • bjrxyz
  • 2015年07月07日 21:24
  • 1845

Boost ptree解析中文字符

Boost ptree解析中文字符flyfish 2015-12-30JSON格式 头文件#include "boost/property_tree/ptree.hpp" #include "boo...
  • flyfish1986
  • flyfish1986
  • 2015年12月30日 15:12
  • 1080

使用 Boost 的 Property Tree 處理 xml

写的不错,原帖:http://viml.nchc.org.tw/blog/paper_info.php?CLASS_ID=1&SUB_ID=1&PAPER_ID=315 Boost C+...
  • yacper
  • yacper
  • 2012年09月27日 17:49
  • 8755

boost property_tree 解析json文件

boost property_tree解析json文件相关文档如下:json_parser 、basic_ptree json_parser: read_json(filename, p...
  • shyanyang
  • shyanyang
  • 2015年03月11日 20:28
  • 4213

Boost ptree 解析 (spirit 库)多线程 崩溃

一直喜欢用boost,但是 ptree 解析在多线程下确实很容易崩溃。其实只需要添加一个宏,一直记不住,现在收藏一下。 原因:ptree解析使用的是语法解析器spirit库,默认非线程安全。 如果...
  • Alsmile
  • Alsmile
  • 2013年11月13日 09:49
  • 2767
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:boost.property_tree解析xml的帮助类以及中文解析问题的解决
举报原因:
原因补充:

(最多只允许输入30个字)