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 中的“//”的等价物。
就遍历树,递归:
#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
假设我有两个 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 中的“//”的等价物。
就遍历树,递归:
#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