递归获取boost属性树中所有值的完整键路径

问题描述

我正在将 XML 文件读入 boost::property_tree 并尝试获取每个值的完整键路径。

  1. boost 是否有内置的方法来做到这一点
  2. 是我的递归出错了吗?

示例输入 - my_file.xml

<foo>
    <bar>abc</bar>
    <baz>
        <buz>def</buz>
    </baz>
</foo>

想要的结果

"foo.bar"
"foo.baz.buz"

实际结果(错误

"foo.bar"
"foo.bar.baz.buz"

代码不太好

void walk_ptree(boost::property_tree::ptree tree,std::unordered_set<std::string>& key_set,std::string parent_key)
{
    if (tree.empty())
    {
        key_set.insert(parent_key);
        return;
    }
    for (auto& it : tree)
    {
        // add a separator between key segments
        if (!parent_key.empty())
        {
            parent_key += ".";
        }
        parent_key += it.first;
        walk_ptree(it.second,key_set,parent_key);
    }
}

boost::property_tree::ptree prop_tree;
boost::property_tree::read_xml("my_file.xml",prop_tree);
std::unordered_set<std::string> key_set{};
walk_ptree(prop_tree,"");

解决方法

for 循环的每次迭代都会增加 parentKey 值,因此在循环结束时它将包含所有子级的名称。使用单独的变量来保存每个节点的键名:

void walk_ptree(const boost::property_tree::ptree& tree,std::unordered_set<std::string>& key_set,const std::string& parent_key)
{
    if (tree.empty())
    {
        key_set.insert(parent_key);
        return;
    }
    for (auto& it : tree)
    {
        std::string key = parent_key;
        // add a separator between key segments
        if (!key.empty())
        {
            key += ".";
        }
        key+= it.first;
        walk_ptree(it.second,key_set,key);
    }
}