You'd need to write a recursive search function, like:
bool find_subtree_helper(ptree const& haystack, ptree const& needle, path_type& path) {
if (std::addressof(haystack) == std::addressof(needle))
return true;
for (auto& child : haystack) {
auto next = path;
next /= child.first;
if ( std::addressof(child.second) == std::addressof(needle)
|| find_subtree_helper(child.second, needle, next))
{
path = next;
return true;
}
}
return false;
}
path_type find_subtree(ptree const& haystack, ptree const& needle) {
path_type path;
if (!find_subtree_helper(haystack, needle, path))
throw std::range_error("not subtree");
return path;
}
Use it like:
Live On Coliru
path_type p = find_subtree(pt_b, pt_e1);
std::cout << p.dump() << std::endl;
Which prints "c2.e1".
Full Listing
Live On Coliru
#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
using namespace boost::property_tree;
using path_type = ptree::path_type;
bool find_subtree_helper(ptree const& haystack, ptree const& needle, path_type& path) {
if (std::addressof(haystack) == std::addressof(needle))
return true;
for (auto& child : haystack) {
auto next = path;
next /= child.first;
if ( std::addressof(child.second) == std::addressof(needle)
|| find_subtree_helper(child.second, needle, next))
{
path = next;
return true;
}
}
return false;
}
path_type find_subtree(ptree const& haystack, ptree const& needle) {
path_type path;
if (!find_subtree_helper(haystack, needle, path))
throw std::range_error("not subtree");
return path;
}
int main()
{
ptree pt0;
pt0.put("a.b.c1",4);
pt0.put("a.b.c2.e1",4);
pt0.put("a.b.c4",4);
pt0.put("a.d",4);
pt0.put("k.m",4);
pt0.put("k.n",4);
ptree &pt_e1 = pt0.get_child("a.b.c2.e1");
ptree &pt_b = pt0.get_child("a.b");
path_type p = find_subtree(pt_b, pt_e1);
std::cout << p.dump() << std::endl;
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…