XML的自定义多极Map序列化和反序列化

主要思路就是递归,传入一个Map类型的字典容器。

打个比方,一个英雄的技能星系,道具星系,武器星系,属性信息等等,都可以封装在一个Map中,而这个Map中的技能是一个map,属性是一些数据,而道具可能是数组等等。

这样一个多极map的序列化应该如何操作?一个序列化函数搞定。

XML解码与编码

*****************根据一个map编码*********************
1⃣️第一个函数就是传一个Map,这是一个入口函数,参数一是写入到的文件路径,第二个参数是需要写入的map

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()));

    }

}

*****************将XML解码到一个Map中*********************
3⃣️这个函数也是接口函数,调用这个函数将把文件写入到一个map,并将这个map返回。参数是目标文件路径,也就是初始化的配置表

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"));

结果如下


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值