使用 Boost C++ 为嵌套标签解析 xml
Posted
技术标签:
【中文标题】使用 Boost C++ 为嵌套标签解析 xml【英文标题】:Parsing xml using Boost c++ for nested tags 【发布时间】:2018-01-17 14:31:29 【问题描述】:我正在尝试使用具有以下结构的 boost 解析 xml 文件:
<root>
<chocos>
<choco>
<color>1</color>
<companies>
<comapany>10</company>
<comapany>11</company>
</companies>
</choco>
<choco>
<color>2</color>
<companies>
<comapany>12</company>
<comapany>13</company>
</companies>
</choco>
</chocos>
</root>
我需要将其存储在以下类中:
class root_info
public:
//some members
std::vector<choco_info> chocos;
class choco_info
int color;
int companies[100];
我写了以下代码,但它显示错误:
没有这样的节点(公司)读取xml文件失败>
代码:
for(const auto& v : pt.get_child("root.chocos"))
choco_info choco;
if(v.first == "choco")
choco.color = v.second.get<unsigned>("color");
int i = 0;
for(const auto& v2 : pt.get_child("companies"))
if( v2.first == "company")
choco.company[i] = v2.second.get<unsigned>("company");
i++;
root.chocos.push_back(choco);
xml 无法更改,因为它已提供给我。主要问题在于如何迭代“chocos”以及“companies”
【问题讨论】:
pt.get_child("companies")
在我看来很可疑。不应该是v.second.get_child("companies")
你甚至没有提到你正在使用什么 boost 库。
@drescherjm:我做了那个改变。它现在显示下一个节点(即“公司”)的相同错误。这是访问该节点的错误方式吗?
@drescherjm:知道了!我需要写 v2.first == "companies" 。
【参考方案1】:
结构化代码有助于降低复杂性:
Live On Coliru
#include <boost/property_tree/xml_parser.hpp>
std::string const sample = R"(<root>
<chocos>
<choco>
<color>1</color>
<companies>
<comapany>10</company>
<comapany>11</company>
</companies>
</choco>
<choco>
<color>2</color>
<companies>
<comapany>12</company>
<comapany>13</company>
</companies>
</choco>
</chocos>
</root>)";
using boost::property_tree::ptree;
using companies_t = std::vector<int>;
struct choco_info
int color;
companies_t companies;
;
using chocos_t = std::vector<choco_info>;
struct root_info
//some members
chocos_t chocos;
;
bool read_companies(ptree const& pt, companies_t& into)
for (auto& [name,child] : pt)
if (name == "comapany") // FIXME
into.push_back(child.get_value<int>());
else
return false;
return true;
bool read_chocos(ptree const& pt, chocos_t& into)
for (auto& [name,child] : pt)
if (name == "choco")
choco_info ci;
ci.color = child.get("color", -1);
if (!read_companies(child.get_child("companies"), ci.companies))
return false;
into.push_back(std::move(ci));
else
return false;
return true;
#include <iostream>
int main()
ptree pt;
std::istringstream iss(sample);
read_xml(iss, pt);
root_info result;
bool ok = true;
try
ok = read_chocos(pt.get_child("root.chocos"), result.chocos);
catch(std::exception const& e)
std::cout << "Exception: " << e.what() << "\n";
ok = false;
if (ok)
std::cout << "Parsed:\n";
for (auto& choco : result.chocos)
std::cout << " - color " << choco.color << "\n";
for (int company : choco.companies)
std::cout << " * company " << company << "\n";
else
std::cout << "Error in input\n";
打印
Parsed:
- color 1
* company 10
* company 11
- color 2
* company 12
* company 13
【讨论】:
我是编译错误:在函数'bool read_companies(const ptree&,company_t&)'中:错误:在'['令牌之前预期的不合格ID(auto&[name,child]:pt)预期' ;' 在 ':' 标记之前 与 read_chocos 函数类似。还显示“‘name’未在此范围内声明”和“‘child’未在此范围内声明” 我已经检查过了,我没有遗漏任何分号或其他需要的标记。以上是关于使用 Boost C++ 为嵌套标签解析 xml的主要内容,如果未能解决你的问题,请参考以下文章
c++ boost xml解析器ptree.get函数——不接受节点名中的空格