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++的序列化与反序列化的想法,如果各位大佬有更好的想法,请赐教