2017-05-30 96 views
0

选择一个子节点的标签,无论位置比方说,我有两个个XML:使用boost :: property_tree

<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中的等价物。

回答

1

只是遍历树,递归:

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 
相关问题