主要思路就是递归,传入一个Map类型的字典容器。
打个比方,一个英雄的技能星系,道具星系,武器星系,属性信息等等,都可以封装在一个Map中,而这个Map中的技能是一个map,属性是一些数据,而道具可能是数组等等。
这样一个多极map的序列化应该如何操作?一个序列化函数搞定。
XML解码与编码
void XML_DOMParser::write_base(const char*filepath,ValueMap pmap)
{
tinyxml2::XMLDocument*pdoc=new tinyxml2::XMLDocument();
if (pdoc==NULL) {
return ;
}
XMLDeclaration*pDel=pdoc->NewDeclaration("xml version=\"1.0\" encoding=\"UTF-8\"");
if (pDel==NULL) {
return ;
}
pdoc->LinkEndChild(pDel);
XMLElement*plistElement=pdoc->NewElement("plist");
plistElement->SetAttribute("version", "1.0");
pdoc->LinkEndChild(plistElement);
for (auto i:pmap){
XMLNode* pDict=pdoc->NewElement(i.first.c_str());
write_base(i.second,pDict,pdoc);
plistElement->LinkEndChild(pDict);
}
pdoc->SaveFile(filepath);
delete pdoc;
}
2⃣️第二个函数是针对第一个函数的子节点的操作,是一个内部函数,非对外接口,可以写成private,进行封装。
//一个Value,可能是Map或者string;父节点;XML文本对象
void XML_DOMParser::write_base(Value vp,XMLNode*pa,tinyxml2::XMLDocument*pdoc)
{
if (vp.getType()==Value::Type::MAP) {
ValueMap pmap=vp.asValueMap();
for (auto i:pmap) {
XMLElement* pDict=pdoc->NewElement(i.first.c_str());
write_base(i.second,pDict,pdoc);
pa->LinkEndChild(pDict);
}
}
else if(vp.getType()==Value::Type::STRING)
{
pa->LinkEndChild(pdoc->NewText(vp.asString().c_str()));
}
}
cocos2d::ValueMap XML_DOMParser::read_xmlitoos_to_map(const char*filepath)
{
ValueMap pmap;
//新建文件类
tinyxml2::XMLDocument*pdoc=new tinyxml2::XMLDocument();
//载入目标文件
pdoc->LoadFile(filepath);
//获取根节点
XMLElement*rootEle=pdoc->RootElement();
//访问该节点
if (rootEle->GetText()!=nullptr) {
pmap[rootEle->Name()]=Value(rootEle->GetText());
}
else{
pmap=read_base_to_map(rootEle);
}
return pmap;
}
4⃣️第二个函数是内部函数,也是内部调用的,可以写成private增加封装
cocos2d::ValueMap XML_DOMParser::read_base_to_map(tinyxml2::XMLElement*rootele)
{
ValueMap pmap;
//获取根节点的第一个子节点temp
XMLElement*temp=rootele->FirstChildElement();
//如果存在,执行遍历
while (temp!=NULL)
{
//不是文本,就是map
if (temp->GetText()!=nullptr) {
pmap[temp->Name()]=Value(temp->GetText());
}
else{
ValueMap child_map;
//访问以temp为根节点的树
child_map=read_base_to_map(temp);
//插入进去
pmap[temp->Name()]=Value(child_map);
}
//访问temp的所有兄弟节点
temp=temp->NextSiblingElement();
}
return pmap;
}
//XML_DOMParser是包含这4个函数的一个类
XML_DOMParser*xp=newXML_DOMParser();
xp->write_base("/Users/mac/Desktop/beifenwork/homework3.xml",xp->read_xmlitoos_to_map("/Users/mac/Desktop/beifenwork/homework.xml"));
结果如下