仅选择Boost ptree的节点

时间:2016-06-17 16:32:13

标签: c++ boost

考虑以下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"))
{
}

但是,因为属性也被视为孩子,所以&#34; modules&#34;的第一个孩子。将是&#34; group&#34;但不是&#34;模块&#34;。 有没有办法只选择属性树的子节点? 一种可能性是检查

if(v.first == "module")

但还有更好的方法吗?

1 个答案:

答案 0 :(得分:2)

您可以在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

这在算法上优于检查每个孩子,但我怀疑它在普通用法上有很大的不同。