使用 C++ 中的 BOOST 库解析嵌套 XML 文件的属性 [英] Parsing a nested XML file for its attributes using BOOST library in c++

查看:39
本文介绍了使用 C++ 中的 BOOST 库解析嵌套 XML 文件的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 XML 文件嵌套如下:

My XML file is nested as follow:

<?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>

我想抓住所有汽车"汽车"下的属性.此外,我希望获得其所有子节点spec"的属性.

I wish to grab all "car" attributes under "cars". Furthermore, I wish to get attributes of all its child node "spec" as well.

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

Currently, my code is similar to one in this question: Parsing nested xml with boost

我能够获取汽车"的属性标签.但是,我无法获取其子元素的属性.即使我成功获取了第一个汽车"所需的所有数据,它也会继续打印与第一个节点相同的子节点属性.

I'm able to get attributes of "car" tag. However, I'm unable to grab its attributes of its children element. Even if I'm successful in grabbing all required data for first "car", it keeps printing its children attributes same as the first node.

推荐答案

假设你有一个像

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]

这篇关于使用 C++ 中的 BOOST 库解析嵌套 XML 文件的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆