Select 一个子节点标记,不管位置如何使用 boost::property_tree

Select a sub node tag regardless the position using boost::property_tree

假设我有两个 XML:

<some><non_important><header><my_value>foo</my_value></header></non_important></some>
<some_1><non_important_1><header_1><my_value>foo</my_value></header_1></non_important_1></some_1>

有没有办法在不指定绝对路径的情况下使用 属性 树从 xml 中提取 my_value?

目前我能做的最好的是:

std::string first("some.non_important.header.my_value");
std::string second("some_1.non_important_1.header_1.my_value");

std::string getMyValue(std::istream& xml,const std::string& path)
{
    pt::ptree tree;
    pt::read_xml(xml, tree);
    return tree.get<std::string>(path);
}

我想我正在寻找的是 XPath 中的“//”的等价物。

就遍历树,递归:

Live On Coliru

#include <boost/property_tree/xml_parser.hpp>
#include <iostream>

using Ptree = boost::property_tree::ptree;
//template <typename Ptree>
bool read_from(std::string& into, Ptree const& pt, std::string const& target) {
    if (auto v = pt.get_optional<std::string>(target)) {
        into = *v;
        return true;
    }
    for (auto& child : pt) {
        if (read_from(into, child.second, target)) return true;
    }

    return false;
}

int main() {
    for (auto text : {
        "<some><non_important><header><my_value>foo</my_value></header></non_important></some>",
        "<some_1><non_important_1><header_1><my_value>foo</my_value></header_1></non_important_1></some_1>",
    })
    {
        boost::property_tree::ptree pt;
        {
            std::istringstream iss(text);
            read_xml(iss, pt);
        }

        std::string my_value;
        if (read_from(my_value, pt, "my_value")) {
            std::cout << "Retrieved value: " << my_value << "\n";
        }
    }
}

版画

Retrieved value: foo
Retrieved value: foo