如何使用Boost XML Parser [英] How to use Boost XML Parser

查看:69
本文介绍了如何使用Boost XML Parser的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经编写了一个XML解析器,用于读取XML文件并将其转换为"Position"类的对象.它工作正常.请在下面查看其代码.

I have written an XML parser for reading an XML file and convert it to an object of my "Position" class. It works fine. Please take a look at its code below.

XML文件:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="15">
<position class_id="0" tracking_level="0" version="0">
    <Degrees>1</Degrees>
    <Minutes>2</Minutes>
    <Seconds>3</Seconds>
    <data class_id="1" tracking_level="0" version="0">
        <Degrees>1</Degrees>
        <Minutes>2</Minutes>
        <Seconds>3</Seconds>
    </data>
</position>
</boost_serialization>

位置等级:

#ifndef XMLMANAGER_POSITION_H
#define XMLMANAGER_POSITION_H

#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>

class Data
{
public:
    int Degrees;
    int Minutes;
    float Seconds;
private:
    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int version){
        ar & BOOST_SERIALIZATION_NVP(Degrees);
        ar & BOOST_SERIALIZATION_NVP(Minutes);
        ar & BOOST_SERIALIZATION_NVP(Seconds);
    }
};
class Position
{

public:
    // every serializable class needs a constructor
    Position() {
        Degrees = 0;
        Minutes = 0;
        Seconds = 0;
    };
    Position(int degrees, int minutes, float seconds){
        Degrees = degrees;
        Minutes = minutes;
        Seconds = seconds;
    };
    int Degrees;
    int Minutes;
    float Seconds;
    Data data;

private:
    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int version){
        ar & BOOST_SERIALIZATION_NVP(Degrees);
        ar & BOOST_SERIALIZATION_NVP(Minutes);
        ar & BOOST_SERIALIZATION_NVP(Seconds);
        ar & BOOST_SERIALIZATION_NVP(data);
    }
};

#endif //XMLMANAGER_POSITION_H

主要功能:

    // Load an Object from XML
    std::ifstream ifs("/tests/r.karimi/XmlManager/data/Output.xml");
    boost::archive::xml_iarchive ixa(ifs);
    Position newPosition;
    try
    {
        ixa >> BOOST_SERIALIZATION_NVP(newPosition);
    }
    catch (std::exception const &ex)
    {
        std::cerr << ex.what() << std::endl;
    }
    std::cout << "Degree " << newPosition.Degrees <<
              " Minutes " << newPosition.Minutes <<
              " Seconds " << newPosition.Seconds << std::endl;
    std::cout << "Degree " << newPosition.data.Degrees <<
              " Minutes " << newPosition.data.Minutes <<
              " Seconds " << newPosition.data.Seconds << std::endl;

现在,我要粘贴以下XML:

Now, I want to pasre the following XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="15">
<position class_id="0" tracking_level="0" version="0">
    <Degrees>0</Degrees>
    <Minutes>0</Minutes>
    <Seconds>0.000000000e+00</Seconds>
    <data class_id="1" tracking_level="0" version="0">
        <Degrees>1</Degrees>
        <Minutes>2</Minutes>
        <Seconds>3</Seconds>
    </data>
    <data class_id="1" tracking_level="0" version="0">
        <Degrees>4</Degrees>
        <Minutes>5</Minutes>
        <Seconds>6</Seconds>
    </data>
</position>
</boost_serialization>

我该怎么办?我尝试了其他解决方案,例如在位置"类中获取数据"类的数组,但是它不起作用.我更喜欢在项目中使用Boost库. (除非不可能!!!)

What should I do? I have tried different solution such as get an array of "Data" class in "Position" class, but it does not work. I prefer to use Boost library for my project. (Unless it is not possible!!!)

推荐答案

Boost 没有没有XML库.

Boost does not have an XML library.

Boost序列化不会读取一般的XML(如)文档.它仅以 读取XML档案.意思是,您无法控制XML.

Boost Serialization doesn't read general XML (like) documents. It reads XML archives only. Meaning, you don't control the XML.

总而言之,您可以简单地用另一个Data成员扩展该类,并且偶然会产生非常相似的XML存档.也许这对您已经足够了:

That all said, you can simply extend the class with another Data member, and it would accidentally result in a very similar XML archive. Perhaps this is good enough for you:

在Coliru上直播

#include <boost/archive/xml_oarchive.hpp>

class Data
{
public:
    int Degrees;
    int Minutes;
    float Seconds;
private:
    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int /*version*/){
        ar & BOOST_SERIALIZATION_NVP(Degrees);
        ar & BOOST_SERIALIZATION_NVP(Minutes);
        ar & BOOST_SERIALIZATION_NVP(Seconds);
    }
};

class Position
{

public:
    // every serializable class needs a constructor
    Position() {
        Degrees = 0;
        Minutes = 0;
        Seconds = 0;
    };
    Position(int degrees, int minutes, float seconds){
        Degrees = degrees;
        Minutes = minutes;
        Seconds = seconds;
    };
    int Degrees;
    int Minutes;
    float Seconds;
    Data data;
    Data data2;

private:
    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int /*version*/){
        ar & BOOST_SERIALIZATION_NVP(Degrees);
        ar & BOOST_SERIALIZATION_NVP(Minutes);
        ar & BOOST_SERIALIZATION_NVP(Seconds);
        ar & boost::serialization::make_nvp("data", data);
        ar & boost::serialization::make_nvp("data", data2);
    }
};

#include <fstream>

int main() {
    Position position;
    position.Degrees = 1;
    position.Minutes = 2;
    position.Seconds = 3;
    position.data = {1,2,3};
    position.data2 = {4,5,6};

    {
        std::ofstream ofs("output.xml");
        boost::archive::xml_oarchive oa(ofs);

        oa << BOOST_SERIALIZATION_NVP(position);
    }
}

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="14">
<position class_id="0" tracking_level="0" version="0">
    <Degrees>1</Degrees>
    <Minutes>2</Minutes>
    <Seconds>3.000000000e+00</Seconds>
    <data class_id="1" tracking_level="0" version="0">
        <Degrees>1</Degrees>
        <Minutes>2</Minutes>
        <Seconds>3.000000000e+00</Seconds>
    </data>
    <data>
        <Degrees>4</Degrees>
        <Minutes>5</Minutes>
        <Seconds>6.000000000e+00</Seconds>
    </data>
</position>
</boost_serialization>

更新

如果您不想控制XML,那就更好了.只需让图书馆做您想做的事即可:

UPDATE

If you DIDN'T want to control the XML, all the better. Just let the library do what you want it to do:

在Coliru上直播

#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/serialization/vector.hpp>

class Data
{
public:
    int Degrees;
    int Minutes;
    float Seconds;
private:
    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int /*version*/){
        ar & BOOST_SERIALIZATION_NVP(Degrees);
        ar & BOOST_SERIALIZATION_NVP(Minutes);
        ar & BOOST_SERIALIZATION_NVP(Seconds);
    }
};

class Position
{

public:
    // every serializable class needs a constructor
    Position() {
        Degrees = 0;
        Minutes = 0;
        Seconds = 0;
    };
    Position(int degrees, int minutes, float seconds){
        Degrees = degrees;
        Minutes = minutes;
        Seconds = seconds;
    };
    int Degrees;
    int Minutes;
    float Seconds;
    std::vector<Data> data;

private:
    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int /*version*/){
        ar & BOOST_SERIALIZATION_NVP(Degrees);
        ar & BOOST_SERIALIZATION_NVP(Minutes);
        ar & BOOST_SERIALIZATION_NVP(Seconds);
        ar & boost::serialization::make_nvp("data", data);
    }
};

#include <fstream>

int main() {
    {
        Position position;
        position.Degrees = 1;
        position.Minutes = 2;
        position.Seconds = 3;
        position.data = { {1,2,3}, {4,5,6 } };

        std::ofstream ofs("output.xml");
        boost::archive::xml_oarchive oa(ofs);

        oa << BOOST_SERIALIZATION_NVP(position);
    }
    {
        std::ifstream ifs("output.xml");
        boost::archive::xml_iarchive ia(ifs);

        Position position;
        ia >> BOOST_SERIALIZATION_NVP(position);
    }
}

在这种情况下,XML 显示为:

In this case, the XML happens to look like:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="14">
<position class_id="0" tracking_level="0" version="0">
    <Degrees>1</Degrees>
    <Minutes>2</Minutes>
    <Seconds>3.000000000e+00</Seconds>
    <data class_id="1" tracking_level="0" version="0">
        <count>2</count>
        <item_version>0</item_version>
        <item class_id="2" tracking_level="0" version="0">
            <Degrees>1</Degrees>
            <Minutes>2</Minutes>
            <Seconds>3.000000000e+00</Seconds>
        </item>
        <item>
            <Degrees>4</Degrees>
            <Minutes>5</Minutes>
            <Seconds>6.000000000e+00</Seconds>
        </item>
    </data>
</position>
</boost_serialization>

这篇关于如何使用Boost XML Parser的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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