c++ - 只选择 Boost ptree 的节点

标签 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"))
{
}

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

if(v.first == "module")

但是有没有更好的办法呢?

最佳答案

您可以使用 equal_range() property_tree 上的成员函数,它返回 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

这在算法上比检查每个 child 要好,尽管我怀疑它在普通用法中有多大区别。

关于c++ - 只选择 Boost ptree 的节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37886341/

相关文章:

c++ - 无锁数据结构中的非 POD 类型

c++ - 我是否需要 1 个读者和 1 个作者的互斥锁,我不介意丢失一些写入?

c++ - opencv MeanShift : which is the area interested?

c++ - 在 Linux Mint 上使用多个版本的 libboost

javascript - 使用 C++ 中的构造函数时 ffi 的返回类型是什么

c++ - Boost program_options将多个配置文件解析结果存储到一个parsed_options中

c++ - 将 FILETIME 转换为可移植时间单位

c++ - 嵌套 for 循环 C++ 中的运行时错误

c++ - 如何迭代 Boost Multi_index 容器的索引?

python-3.x - 为什么 python 公开的 boost::gregorian::date 不是到处可用?