xml遍历文件夹vector_如何遍历XML结构的boost :: property_tree

I have an XML structure along the lines of:

Which is being read into a boost::property_tree, There are 1..Many s, and then at an arbitrary depth within that element there could be 1..Many s

Is there a way to iterate over the directly (in a single loop) in the order that they appear in the doc?

I have looked at equal_range

void iterateOverPoints()

{

const char* test =

"<?xml version=\"1.0\" encoding=\"utf-8\"?>"

""

""

""

""

""

""

""

""

""

""

""

""

"";

boost::property_tree::ptree message;

std::istringstream toParse(test);

boost::property_tree::read_xml(toParse,result_tree);

//Now we need to locate the point elements and set the x/y accordingly.

std::pair< boost::property_tree::ptree::const_assoc_iterator,

boost::property_tree::ptree::const_assoc_iterator > result =

message.equal_range("ElementIWant");

for( boost::property_tree::ptree::const_assoc_iterator it = result.first;

it != result.second; ++it )

{

std::cout << it->first << " : ";

const boost::property_tree::ptree& x = it->second.get_child( ".x" );

const boost::property_tree::ptree& y = it->second.get_child( ".y" );

std::cout << x.get_value() << "," << y.get_value() << "\n";

}

return;

}

However it seems to fail to return nodes (Which I suspect is because equal_range works at the level of the tree node supplied) Which brings me to the question above...

解决方案

It is not possible to iterate over all elements directly; the documentation says

There is no way to iterate over the entire tree.

Now, you could use recursion, and apply STL algorithms at each level to mimic that; it does not fit your requirement of doing this in a single loop in my sample below, but it does works:

template

void collect(InputIt first, InputIt last, OutputIt dest, Compare comp)

{

typedef typename std::iterator_traits::reference reference;

std::copy_if (

first, last, dest,

[comp] (reference what) { return comp(what.first); });

std::for_each (

first, last,

[dest, comp] (reference what) { collect(what.second.begin(), what.second.end(), dest, comp); });

}

std::vector<:pair ptree>> match;

collect(

xml.begin (), xml.end (), std::back_inserter(match),

[] (const std::string& key) { return key == "ElementIWant"; });

for (auto pair: match)

{

std::cout << pair.first << std::endl;

}

Here is a version that is "fully" recursive and preserve the order of appearance:

template

void collect_recursive(InputIt first, InputIt last, OutputIt dest, Compare comp)

{

typedef typename std::iterator_traits::reference reference;

if (first == last)

{

return;

}

auto begin = first->second.begin ();

auto end = first->second.end ();

if (begin != end)

{

collect_recursive (begin, end, dest, comp);

}

if (comp (first->first))

{

dest = *first;

}

collect_recursive (++first, last, dest, comp);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值