使用Boost迭代xml文件 [英] Iterating on xml file with boost
本文介绍了使用Boost迭代xml文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我是boost和xml的新手,我正在尝试扫描xml文件并保存一些特定值.
I am new with boost and xml and I am trying to scan an xml file and save some specific values.
我阅读了这篇文章和我的问题是:如果xml包含几个< sked>
,如何对它们进行迭代?
I read this article and my question is: if the xml contains several <sked>
, how do I iterate both of them?
也许
BOOST_FOREACH ()
BOOST_FOREACH () // nested loop
让我们按如下方式说出给定的xml文件(目的是保存两个 ID ):
lets say the given xml file as follow (the purpose is to save both IDs):
<?xml version="1.0"? encoding="utf-8"?>
<arrayOfSked>
<sked>
<ID> 1 </ID>
<version>2</version>
<flight>
<carrier>BA</carrier>
<number>4001</number>
<precision>0.1</precision>
</flight>
<flight cancelled="true">
<carrier>BA</carrier>
<number>4002</number>
<precision>0.2</precision>
</flight>
</sked>
<sked>
<ID> 2 </ID>
<version>2</version>
<flight>
<carrier>BA</carrier>
<number>4001</number>
<precision>0.1</precision>
</flight>
<flight cancelled="true">
<carrier>BA</carrier>
<number>4002</number>
<precision>0.2</precision>
</flight>
</sked>
</arrayOfSked>
推荐答案
Taking some inspiration from this older answer of mine (boost::ptree find? or how to access deep arrays? C++), write a function to visit the tree nodes:
template <typename Tree, typename Out>
Out enumerate_nodes(Tree const& pt, typename Tree::path_type path, Out out) {
if (path.empty())
return out;
if (path.single()) {
auto name = path.reduce();
for (auto& child : pt)
{
if (child.first == name)
*out++ = child.second;
}
} else {
auto head = path.reduce();
for (auto& child : pt) {
if (head == "*" || child.first == head) {
out = enumerate_nodes(child.second, path, out);
}
}
}
return out;
}
现在您可以轻松读取文件:
Now you can simply read the file:
using boost::property_tree::ptree;
ptree pt;
{
std::ifstream ifs("input.txt");
read_xml(ifs, pt);
}
并收集航班:
std::vector<std::reference_wrapper<ptree const> > flights;
enumerate_nodes<ptree>(pt, "arrayOfSked.sked.flight", back_inserter(flights));
for (ptree const& flight : flights) {
std::cout << "Canceled:\t" << (flight.get("<xmlattr>.cancelled", false)?"yes":"no") << "\n";
std::cout << "Carrier:\t" << flight.get("carrier", "?") << "\n";
std::cout << "Number:\t" << flight.get("number", 0) << "\n";
std::cout << "Precision:\t" << flight.get("precision", 0.0) << "\n";
std::cout << "------------------------------\n";
}
哪些印刷品:
Canceled: no
Carrier: BA
Number: 4001
Precision: 0.1
------------------------------
Canceled: yes
Carrier: BA
Number: 4002
Precision: 0.2
------------------------------
Canceled: no
Carrier: BA
Number: 4001
Precision: 0.1
------------------------------
Canceled: yes
Carrier: BA
Number: 4002
Precision: 0.2
------------------------------
在线完整演示
#include <boost/property_tree/xml_parser.hpp>
#include <iostream>
template <typename Tree, typename Out>
Out enumerate_nodes(Tree const& pt, typename Tree::path_type path, Out out) {
if (path.empty())
return out;
if (path.single()) {
auto name = path.reduce();
for (auto& child : pt)
{
if (child.first == name)
*out++ = child.second;
}
} else {
auto head = path.reduce();
for (auto& child : pt) {
if (head == "*" || child.first == head) {
out = enumerate_nodes(child.second, path, out);
}
}
}
return out;
}
int main() {
using boost::property_tree::ptree;
ptree pt;
{
std::ifstream ifs("input.txt");
read_xml(ifs, pt);
}
std::vector<std::reference_wrapper<ptree const> > flights;
enumerate_nodes<ptree>(pt, "arrayOfSked.sked.flight", back_inserter(flights));
for (ptree const& flight : flights) {
std::cout << "Canceled:\t" << (flight.get("<xmlattr>.cancelled", false)?"yes":"no") << "\n";
std::cout << "Carrier:\t" << flight.get("carrier", "?") << "\n";
std::cout << "Number:\t" << flight.get("number", 0) << "\n";
std::cout << "Precision:\t" << flight.get("precision", 0.0) << "\n";
std::cout << "------------------------------\n";
}
}
这篇关于使用Boost迭代xml文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文