使用c++中的BOOST库解析嵌套XML文件的属性



我的XML文件嵌套如下:

<?xml version="1.0" encoding="utf-8"?>
<root>
<type>
<cars>
<car name="Garfield" weight="4Kg">
<spec serial_="e_54" source ="petrol" mileage="56"/>
<spec serial_="e_52" source="diesel" mileage="52"/>
<spec serial_="m_22" source="electric" mileage="51"/>
<additions source="steam" convert="153 0 1 0"/>
</car>
<car name="Awesome" weight="3Kg">
<spec serial_="t_54" source="petrol" mileage="16"/>
<spec serial_="t_52" source="wind" mileage="62"/>
<spec serial_="t_22" source="electric" mileage="81"/>
<additions source="water" convert="123 1 1 0"/>
</car>
</cars>
<planes>
<plane id="231" name ="abc">
<utilities serial_="e456" part="567"/>
</plane>
</type>
</root>

我希望抓住所有的"车"。"汽车"下的属性。此外,我希望获得其所有子节点"规格"的属性。。

目前,我的代码与这个问题中的代码类似:使用boost解析嵌套xml

我可以得到"汽车"的属性标签。但是,我无法获取其子元素的属性。即使我成功地获取了第一个"car"所需的所有数据,它仍然像第一个节点一样打印它的子属性。

假设您有一个像

这样的目标结构
struct Car {
std::string name, weight;
struct Spec {
std::string serial_, source;
double mileage;
};
std::vector<Spec> specs;
};

我会写像

这样的代码
for (auto& [key, node] : pt.get_child("root.type.cars")) {
if ("car" == key) {
Car car;
parse(node, car);
std::cout << car << "n";
}
}

其中parse为:

static bool parse(ptree const& node, Car& into)  {
into.name   = node.get<std::string>("<xmlattr>.name");
into.weight = node.get<std::string>("<xmlattr>.weight");
for (auto& [name, child] : node) {
if (name == "spec") {
into.specs.emplace_back();
if (!parse(child, into.specs.back())) {
return false;
}
}
}
return true;
}

当然,Spec也有类似的过载:

static bool parse(ptree const& node, Car::Spec& into) {
into.serial_ = node.get<std::string>("<xmlattr>.serial_");
into.source  = node.get<std::string>("<xmlattr>.source");
into.mileage = node.get<double>("<xmlattr>.mileage");
return true;
}

现场演示

#include <boost/property_tree/xml_parser.hpp>
using boost::property_tree::ptree;
#include <iostream>
struct Car {
std::string name, weight;
struct Spec {
std::string serial_, source;
double mileage;
};
std::vector<Spec> specs;
};
static bool parse(ptree const& node, Car::Spec& into) {
into.serial_ = node.get<std::string>("<xmlattr>.serial_");
into.source  = node.get<std::string>("<xmlattr>.source");
into.mileage = node.get<double>("<xmlattr>.mileage");
return true;
}
static bool parse(ptree const& node, Car& into)  {
into.name   = node.get<std::string>("<xmlattr>.name");
into.weight = node.get<std::string>("<xmlattr>.weight");
for (auto& [name, child] : node) {
if (name == "spec") {
into.specs.emplace_back();
if (!parse(child, into.specs.back())) {
return false;
}
}
}
return true;
}
static std::ostream& operator<<(std::ostream& os, Car const& car) {
os << "Name: " << car.name << ", Weight: " << car.weight;
for (auto& spec : car.specs) {
os << "n -- [" << spec.serial_ << "; " << spec.source << "; "
<< spec.mileage << "]";
}
return os;
}
int main() 
{
boost::property_tree::ptree pt;
{
std::ifstream ifs("input.xml");
read_xml(ifs, pt);
}
for (auto& [key, node] : pt.get_child("root.type.cars")) {
if ("car" == key) {
Car car;
parse(node, car);
std::cout << car << "n";
}
}
}

打印

Name: Garfield, Weight: 4Kg
-- [e_54; petrol; 56]
-- [e_52; diesel; 52]
-- [m_22; electric; 51]
Name: Awesome, Weight: 3Kg
-- [t_54; petrol; 16]
-- [t_52; wind; 62]
-- [t_22; electric; 81]

相关内容

  • 没有找到相关文章

最新更新