您可以编写自己的“选择器”查询,因此可以编写以下内容:
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);该
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;}作为简单的工作演示打印:
Specific children but in arrays: andthis6, Single wildcard: andthis6, andthis7, andthis8, andthis9, Two wildcards: andthis1, andthis2, andthis3, andthis4, andthis6, andthis7, andthis8, andthis9,
那就是下面的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" }] }] }] }] }}[Live On Coliru](http://coliru.stacked-crooked.com/a/2a57e51a163150f6)
完整清单
[Live On Coliru](http://coliru.stacked-crooked.com/a/75719ffb76659264)
#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);}


