【问题标题】:Select only nodes of Boost ptree只选择Boost ptree的节点
【发布时间】:2016-06-17 16:32:12
【问题描述】:

考虑以下 XML 文件:

<debug>
    <modules group="0">
        <module>Finance</module>
        <module>Admin</module>
        <module>HR</module>
    </modules>
</debug>

使用 Boost.PropertyTree 可以遍历节点的子节点:

BOOST_FOREACH(ptree::value_type &v, pt.get_child("debug.modules"))
{
}

但是由于属性也被视为子属性,因此“模块”的第一个子属性将是“组”而不是“模块”。 有没有办法只选择属性树的子节点? 一种可能性是检查

if(v.first == "module")

但是有没有更好的方法?

【问题讨论】:

    标签: c++ boost


    【解决方案1】:

    您可以在property_tree 上使用equal_range() 成员函数,它返回一个std::pair 迭代器,用特定键标记一系列子节点。然后就可以使用Boost Range对范围进行操作了。

    这可以很好地与 C++11 的 auto 类型说明符和基于范围的 for 循环(或 BOOST_AUTOBOOST_FOREACH)配合使用:

    #include <iostream>
    #include <sstream>
    #include <boost/property_tree/ptree.hpp>
    #include <boost/property_tree/xml_parser.hpp>
    #include <boost/range/iterator_range.hpp>
    
    static const std::string input =
       "<debug>"
       " <modules group=\"0\">"
       "  <module>Finance</module>"
       "  <module>Admin</module>"
       "  <module>HR</module>"
       " </modules>"
       "</debug>";
    
    int main() {
       std::istringstream istream(input);
       boost::property_tree::ptree ptree;
       boost::property_tree::read_xml(istream, ptree);
    
       const auto range = ptree.get_child("debug.modules").equal_range("module");
       for (auto& child : boost::make_iterator_range(range)) {
          std::cout << child.first << std::endl;
       }
    
       return 0;
    }
    

    Demo on CoLiRu

    这在算法上比检查每个孩子要好,尽管我怀疑它在日常使用中会有很大的不同。

    【讨论】:

    • 完美。这就是我寻找的解决方案。这对我来说可以。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多