考虑以下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")
但还有更好的方法吗?
答案 0 :(得分:2)
您可以在property_tree
上使用equal_range()
成员函数,该函数返回std::pair
个迭代器,用于标记具有特定键的一系列子节点。然后,您可以使用Boost Range来操作范围。
这适用于C ++ 11的auto
类型说明符和基于范围的for循环(或BOOST_AUTO
和BOOST_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;
}
这在算法上优于检查每个孩子,但我怀疑它在普通用法上有很大的不同。