Dru*_*ide 3 json boost boost-propertytree c++11
我现在已经尝试了太多时间来从 boost 库访问 json_reader ptree。
\n\n我有一个经常封装的 json 文件:(pseudo-json:)
\n\n"Foo": {\n "nameofFoo:"foofoo"\n "Bar": [{\n "BarFoo": \n { BarFooDeep: { \n BarFooDeepDeep: { \n "BarFooValue1": 123 \n "BarFooValue2" : 456\n }\n }\n }\n "FooBar": [ {\n "FooBarDeep" :[ {\n FooBarDeepDeep:[ {\n FooBarValue1: "ineedthis"\n FooBarValue2: "andthis"\n } ]\n FooBarDeepDeep1:[ {\n FooBarValue1: "ineedthis"\n FooBarValue2: "andthis"\n } ]\n "FooBarDeep" :[ {\n FooBarDeepDeep2:[ {\n FooBarValue1: "ineedthis"\n FooBarValue2: "andthis"\n } ]\n FooBarDeepDeep3:[ {\n FooBarValue1: "ineedthis"\n FooBarValue2: "andthis"\n } ]\nand so on .... won t complete this now...\nRun Code Online (Sandbox Code Playgroud)\n\n现在我只需要获取所有FooBar的FooBarValue1和FooBarValue2。
\n\n我知道 ptree 将数组与空子元素 ("") 放在一起
\n\n我可以通过递归迭代所有子项来访问所有成员。
\n\n但是有没有更好的方法来访问特殊值呢?
\n\nptree如何找到作品?我总是遇到编译器错误...
\n\nptree jsonPT;\nread_json( JSON_PATH, jsonPT);\nptree::const_iterator myIT = jsonPT.find("FooBarValue1");\ndouble mlat = boost::lexical_cast<int>(myIT->second.data());\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n\n错误: 从\n \xe2\x80\x98boost::property_tree::basic_ptree,\n std::basic_string >::assoc_iterator\xe2\x80\x99 转换为非标量类型\n \xe2\x80\x98boost:: property_tree::basic_ptree,\n std::basic_string >::const_iterator\xe2\x80\x99 请求\n ptree::const_iterator myIT = jsonPT.find("FooBarValue1");
\n
谁能给我一个有用的提示如何访问这个 ptree?!?
\n正如我评论的链接答案(Boost.PropertyTree subpathprocessing)中所暗示的,您可以编写自己的“选择器”查询,这样您就可以编写如下内容:
read_json("input.txt", pt);
std::ostream_iterator<std::string> out(std::cout, ", ");
std::cout << "\nSpecific children but in arrays: ";
enumerate_path(pt, "Foo.Bar..FooBar..FooBarDeep1..FooBarDeepDeep6..FooBarValue2", out);
std::cout << "\nSingle wildcard: ";
enumerate_path(pt, "Foo.Bar..FooBar..FooBarDeep1..*..FooBarValue2", out);
std::cout << "\nTwo wildcards: ";
enumerate_path(pt, "Foo.Bar..FooBar..*..*..FooBarValue2", out);
Run Code Online (Sandbox Code Playgroud)
该enumerate_path函数不需要太复杂并且可以接受任何输出迭代器(所以你back_inserter(some_vector)也可以):
template <typename Tree, typename Out, typename T = std::string>
Out enumerate_path(Tree const& pt, typename Tree::path_type path, Out out) {
if (path.empty())
return out;
if (path.single()) {
*out++ = pt.template get<T>(path);
} else {
auto head = path.reduce();
for (auto& child : pt) {
if (head == "*" || child.first == head) {
out = enumerate_path(child.second, path, out);
}
}
}
return out;
}
Run Code Online (Sandbox Code Playgroud)
作为简单的工作演示打印:
Specific children but in arrays: andthis6,
Single wildcard: andthis6, andthis7, andthis8, andthis9,
Two wildcards: andthis1, andthis2, andthis3, andthis4, andthis6, andthis7, andthis8, andthis9,
Run Code Online (Sandbox Code Playgroud)
即使用以下input.txt:
{
"Foo": {
"nameofFoo": "foofoo",
"Bar": [{
"BarFoo": {
"BarFooDeep": {
"BarFooDeepDeep": {
"BarFooValue1": 123,
"BarFooValue2": 456
}
}
},
"FooBar": [{
"FooBarDeep0": [{
"FooBarDeepDeep1": [{
"FooBarValue1": "ineedthis1",
"FooBarValue2": "andthis1"
}],
"FooBarDeepDeep2": [{
"FooBarValue1": "ineedthis2",
"FooBarValue2": "andthis2"
}]
},
{
"FooBarDeepDeep3": [{
"FooBarValue1": "ineedthis3",
"FooBarValue2": "andthis3"
}],
"FooBarDeepDeep4": [{
"FooBarValue1": "ineedthis4",
"FooBarValue2": "andthis4"
}]
}],
"FooBarDeep1": [{
"FooBarDeepDeep6": [{
"FooBarValue1": "ineedthis6",
"FooBarValue2": "andthis6"
}],
"FooBarDeepDeep7": [{
"FooBarValue1": "ineedthis7",
"FooBarValue2": "andthis7"
}]
},
{
"FooBarDeepDeep8": [{
"FooBarValue1": "ineedthis8",
"FooBarValue2": "andthis8"
}],
"FooBarDeepDeep9": [{
"FooBarValue1": "ineedthis9",
"FooBarValue2": "andthis9"
}]
}]
}]
}]
}
}
Run Code Online (Sandbox Code Playgroud)
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <iostream>
template <typename Tree, typename Out, typename T = std::string>
Out enumerate_path(Tree const& pt, typename Tree::path_type path, Out out) {
if (path.empty())
return out;
if (path.single()) {
*out++ = pt.template get<T>(path);
} else {
auto head = path.reduce();
for (auto& child : pt) {
if (head == "*" || child.first == head) {
out = enumerate_path(child.second, path, out);
}
}
}
return out;
}
int main() {
std::ostream_iterator<std::string> out(std::cout, ", ");
using namespace boost::property_tree;
ptree pt;
read_json("input.txt", pt);
std::cout << "\nSpecific children but in arrays: ";
enumerate_path(pt, "Foo.Bar..FooBar..FooBarDeep1..FooBarDeepDeep6..FooBarValue2", out);
std::cout << "\nSingle wildcard: ";
enumerate_path(pt, "Foo.Bar..FooBar..FooBarDeep1..*..FooBarValue2", out);
std::cout << "\nTwo wildcards: ";
enumerate_path(pt, "Foo.Bar..FooBar..*..*..FooBarValue2", out);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6035 次 |
| 最近记录: |