Boost Property Tree读取JSON数组子对象属性失败问题排查
问题原因及解决办法
你这代码里踩了两个典型的坑,咱们一个个说清楚:
1. 内层遍历用错变量,导致输出空值
你在遍历每个action的属性时,犯了一个低级的变量混淆错误:
for (ptree::value_type &attr : action) MLOG("\t2. [%s][%s]\n", p.first.c_str(), p.second.data().c_str());
这里的p是外层循环(遍历model_actions数组元素)的变量,而当前遍历属性的变量是attr!你打印的始终是数组元素的空键(老版本Boost处理数组的特殊方式)和数组元素整个ptree的空data,自然输出就是[][]。
只要把打印语句里的p换成attr,这部分就能正常输出属性的键和值了。
2. Boost 1.53 Property Tree对JSON数组的特殊处理
Boost 1.53的property tree对JSON的实现并不完全遵循标准,它把JSON数组解析成一个包含多个**空键("")**子节点的ptree:
- 第一个循环里,
model_actions对应的是数组容器本身,它自己没有直接的data()值,所以输出1. [model_actions][]是正常的; - 当你遍历
pt.get_child("model_actions")时,每个数组元素的p.first都是空字符串,这是老版本Boost处理数组的固定方式,和根节点下的普通键值对(比如model_json_version)逻辑不同,所以输出格式和第一个循环的普通键值对有差异。
修正后的代码
// 遍历根节点的子节点 for (ptree::value_type &p : pt) { MLOG("1. [%s][%s]\n", p.first.c_str(), p.second.data().c_str()); } // 遍历model_actions数组中的每个元素 for (ptree::value_type &p : pt.get_child("model_actions")) { auto& action = p.second; MLOG("\taction_type [%s]\n", action.get<string>("action_type").c_str()); // 遍历当前action的所有属性,注意使用attr变量 for (ptree::value_type &attr : action) { MLOG("\t2. [%s][%s]\n", attr.first.c_str(), attr.second.data().c_str()); } }
修正后的输出
运行修正后的代码,你会得到符合预期的输出:
1. [model_json_version][333] 1. [model_actions][] action_type [rep_processor] 2. [action_type][rep_processor] 2. [rp_type][basic_cln] action_type [feat_generator] 2. [action_type][feat_generator] 2. [tags][numeric]
内容的提问来源于stack exchange,提问作者ihadanny
相关产品推荐
相关产品推荐

