基于C++的tinyxml2的序列化以及反序列化

1.定义数据结构

 此处先定义一个嵌套的结构体

typedef struct
{
    double ChildParam1 ;
    string ChildParam2;
}ChildInfo1;

typedef struct
{
    string ChildParam1;
    double ChildParam2 ;
    double ChildParam3 ;
}ChildInfo2;


typedef struct
{
    ChildInfo1 ChildInfo1;
    ChildInfo2 ChildInfo2;
}RootInfo;

2.定义类函数

针对结构体定义一个序列化以及反序列化的类

class CRootConfig
{
public:
    int Read_config(std::string file_path);
    int Write_config(std::string file_path);
    void Get_Root_info( RootInfo* Root_info);
    void Set_Root_info( RootInfo* Root_info);
public:
    CRootConfig();
    ~CRootConfig();
private:
    RootInfo Root_info_pri;
};

3.序列化

int CRootConfig::Write_config(std::string file_path)
{
    XMLDocument doc;

    XMLDeclaration* declaration = doc.NewDeclaration();
    doc.InsertFirstChild(declaration);


    XMLElement* RootInfoElem = doc.NewElement("RootInfo");
    doc.InsertEndChild(RootInfoElem);

    XMLElement* ChildInfo1Elem = doc.NewElement("ChildInfo1");
    RootInfoElem->InsertEndChild(ChildInfo1Elem);

    XMLElement* ChildParam1Elem = doc.NewElement("ChildParam1");
    ChildParam1Elem->SetText(Root_info_pri.ChildInfo1.ChildParam1);
    ChildInfo1Elem->InsertEndChild(ChildParam1Elem);

    XMLElement* ChildParam2Elem = doc.NewElement("ChildParam2");
    ChildParam2Elem->SetText(Root_info_pri.ChildInfo1.ChildParam2.c_str());
    ChildInfo1Elem->InsertEndChild(ChildParam2Elem);



    XMLElement* ChildInfo2Elem = doc.NewElement("ChildInfo2");
    RootInfoElem->InsertEndChild(ChildInfo2Elem);

    ChildParam1Elem = doc.NewElement("ChildParam1");
    ChildParam1Elem->SetText(Root_info_pri.ChildInfo2.ChildParam1.c_str());
    ChildInfo2Elem->InsertEndChild(ChildParam1Elem);

    ChildParam2Elem = doc.NewElement("ChildParam2");
    ChildParam2Elem->SetText(Root_info_pri.ChildInfo2.ChildParam2);
    ChildInfo2Elem->InsertEndChild(ChildParam2Elem);

    XMLElement* ChildParam3Elem = doc.NewElement("ChildParam3");
    ChildParam3Elem->SetText(Root_info_pri.ChildInfo2.ChildParam3);
    ChildInfo2Elem->InsertEndChild(ChildParam3Elem);


    return doc.SaveFile(file_path.c_str());
}

4.反序列化

int CRootConfig::Read_config(std::string file_path)
{  
    XMLDocument doc;
    string value, text;
    //导入xml文件
    int res = doc.LoadFile(file_path.c_str());
    if (res != XML_SUCCESS)
    {
        return res;
    }
    //判断头文件是否为空
    XMLElement* rootNode = doc.RootElement();
    if (rootNode == NULL)
    {
        return res;
    }

    XMLElement* ChildInfo1 = rootNode->FirstChildElement("ChildInfo1");
    XMLElement* ChildInfo1Child = ChildInfo1->FirstChildElement();
    while (ChildInfo1Child)
    {
        // surfaceChild->Value() 是获取节点的名称
        value = ChildInfo1Child->Value();
        if (value == "ChildParam1")
        {
            value = ChildInfo1Child->Value();
            text = ChildInfo1Child->GetText();
            Root_info_pri.ChildInfo1.ChildParam1 = std::stod(text);
            std::cout << value << ": " << text << std::endl;
        }
        if (value == "ChildParam2")
        {
            value = ChildInfo1Child->Value();
            text = ChildInfo1Child->GetText();
            Root_info_pri.ChildInfo1.ChildParam2 = text;
            std::cout << value << ": " << text << std::endl;
        }
        ChildInfo1Child = ChildInfo1Child->NextSiblingElement();
    }

    XMLElement* ChildInfo2 = rootNode->FirstChildElement("ChildInfo2");
    XMLElement* ChildInfo2Child = ChildInfo2->FirstChildElement();
    while (ChildInfo2Child)
    {
        // surfaceChild->Value() 是获取节点的名称
        value = ChildInfo2Child->Value();
        if (value == "ChildParam1")
        {
            value = ChildInfo2Child->Value();
            text = ChildInfo2Child->GetText();
            Root_info_pri.ChildInfo2.ChildParam1 = text;
            std::cout << value << ": " << text << std::endl;
        }
        if (value == "ChildParam2")
        {
            value = ChildInfo2Child->Value();
            text = ChildInfo2Child->GetText();
            Root_info_pri.ChildInfo2.ChildParam2 = std::stod(text);
            std::cout << value << ": " << text << std::endl;
        }
        if (value == "ChildParam3")
        {
            value = ChildInfo2Child->Value();
            text = ChildInfo2Child->GetText();
            Root_info_pri.ChildInfo2.ChildParam2 = std::stod(text);
            std::cout << value << ": " << text << std::endl;
        }
        ChildInfo2Child = ChildInfo2Child->NextSiblingElement();
    }

}

5.Get&Set

 实际的参与序列化与反序列化的对象是类的私有成员,为例让外界的数据变化不会影响原本数据所以需要让外界数据从类中获取或者赋值类中的实际对象,保障数据正确性

void CRootConfig::Get_Root_info(RootInfo *Root_info)
{
    *Root_info = Root_info_pri;
}



void CRootConfig::Set_Root_info(RootInfo *Root_info)
{
    Root_info_pri = *Root_info;
}

6.Test

    CRootConfig CRootConfig;

    RootInfo RootInfo;


    CRootConfig.Read_config("E:\\123.xml");
    CRootConfig.Get_Root_info(&RootInfo);

    RootInfo.ChildInfo1.ChildParam1 = 111;
    RootInfo.ChildInfo1.ChildParam2 = "Hello";
    RootInfo.ChildInfo2.ChildParam1 = "World";
    RootInfo.ChildInfo2.ChildParam2 = 222;
    RootInfo.ChildInfo2.ChildParam3 = 333;

    CRootConfig.Set_Root_info(&RootInfo);
    CRootConfig.Write_config("E:\\321.xml");

7.结果

 

8.个人思考

 序列化的思路:就是将对象的每个节点提出来拼凑成XML的文本

 反序列化的思路:就是将XML文件的节点全部提取出来,对应的赋值给结构体对象的变量中去

Get&Set目的就是为了数据不容易被修改而设计的

上面的代码还有很大的优化空间

对于C++的序列化与反序列化的想法,如果各位大佬有更好的想法,请赐教

  • 14
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
tinyxml2是一个轻量级的XML解析库,它也提供了方便的序列化功能。以下是一个简单的示例,将一个类的对象序列化XML文档: ```c++ #include "tinyxml2.h" #include <iostream> #include <string> using namespace tinyxml2; class Person { public: std::string name; int age; Person() {} Person(const std::string& n, int a) : name(n), age(a) {} void Serialize(XMLNode* parent) const { XMLDocument* doc = parent->GetDocument(); XMLElement* elem = doc->NewElement("Person"); elem->SetAttribute("name", name.c_str()); elem->SetAttribute("age", age); parent->InsertEndChild(elem); } void Deserialize(const XMLNode* parent) { const XMLElement* elem = parent->FirstChildElement("Person"); if (elem) { name = elem->Attribute("name"); age = elem->IntAttribute("age"); } } }; int main() { XMLDocument doc; XMLNode* rootNode = doc.NewElement("Root"); doc.InsertFirstChild(rootNode); Person p1("Alice", 30); Person p2("Bob", 25); p1.Serialize(rootNode); p2.Serialize(rootNode); doc.SaveFile("output.xml"); return 0; } ``` 在这个示例中,我们定义了一个包含姓名和年龄属性的`Person`类,并实现了`Serialize`和`Deserialize`方法。`Serialize`方法将对象序列化为一个XML元素,`Deserialize`方法从一个XML元素中反序列化对象。 在`main`函数中,我们创建一个XML文档和一个根节点。然后,我们创建两个`Person`对象并将它们序列化XML元素,最后将它们作为子节点添加到根节点中。最后,我们将XML文档保存到文件中。 输出XML文件内容如下: ```xml <?xml version="1.0"?> <Root> <Person name="Alice" age="30"/> <Person name="Bob" age="25"/> </Root> ``` 这是一个简单的示例,你可以根据你的需求扩展它。注意,tinyxml2支持更高级别的序列化功能,例如序列化对象的嵌套等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值