tinyxml2的使用

来源:互联网 发布:开源软件许可翻译 编辑:程序博客网 时间:2024/05/29 06:49

       学习使用tinyxml2,参考https://www.cnblogs.com/happykoukou/p/6307257.html,以及官方tinyxml2的test。

       主要知识:

XMLDocument doc;//创建一个dom对象doc.LoadFile();doc.Parse(); //将字符串转为dom对象auto key = doc.NewElement(const char* keyName);//创建一个keydoc.NewText(const char*);//创建一个valueInsertEndChild(key)FirstChildElement(const char*);GetText();SetText(const char*);NextSiblingElement();//兄弟节点

country.hpp

#pragma once//删除指针#define SAFE_DELETE(pRet) if(pRet != NULL) {delete pRet;pRet = NULL;}//检查xml中的键是否存在,xml的结构已知,若不存在,直接退出#define KEY_IS_NULL(key) if(key == nullptr){printf("%s is not found\n",#key);exit(-1);}//为了简单化,以下几个类全部成员函数为publicclass Province;class City;class City{public:    std::string name;    City(const std::string &name):name(name){}};class Province{public:    std::string name;    std::vector<City> vCities;    Province(const std::string &name):name(name){}    Province(){}};class Country{public:    std::string name;    std::vector<Province> vProvinces;public:    Country(const std::string &name):name(name){}    Country(){}        /**     *  将本类的成员变量序列化到一个固定格式的xml文件中     *  采用模板,可以不需要写 tinyxml2的头文件     */    template<typename T>    int parseXML(T &doc, const std::string &fileName)    {        //xml头        //R"(string)", string可以以原来的形式存在,“” 不需要转义符        const char *declaration = R"(<?xml version="1.0" encoding="UTF-8"?>)";                //将字符串解析到dom对象中        doc.Parse(declaration);        //new 一个 key        //序列化std::string name;        auto roof = doc.NewElement("country");        auto keyCountryName = doc.NewElement("name");                //插入value        keyCountryName->InsertEndChild(doc.NewText(name.c_str()));                //插入</>        roof->InsertEndChild(keyCountryName);        doc.InsertEndChild(roof);        //序列化std::vector<Province> vProvinces;        for(auto province : vProvinces)        {            auto keyProvince = doc.NewElement("province");            roof->InsertEndChild(keyProvince);            auto keyProvinceName = doc.NewElement("name");            keyProvinceName->InsertEndChild(doc.NewText(province.name.c_str()));            keyProvince->InsertEndChild(keyProvinceName);                        auto keyCities = doc.NewElement("cities");            keyProvince->InsertEndChild(keyCities);            //序列化std::vector<City> vCities;            for(auto city : province.vCities)            {                auto keyCity = doc.NewElement("city");                keyCity->InsertEndChild(doc.NewText(city.name.c_str()));                keyCities->InsertEndChild(keyCity);            }        }        //保存为xml文件        return doc.SaveFile(fileName.c_str());    }    //反序列化xml文件成一个对象    template<typename T>    int convertXMLToObject(T &doc, const std::string &fileName)    {        int ret = doc.LoadFile(fileName.c_str());        if(ret)        {            return ret;        }        //查找key,如果不存在,则退出程序。        auto keyCountry  = doc.FirstChildElement("country");        KEY_IS_NULL(keyCountry);        auto keyCountryName = keyCountry->FirstChildElement("name");        KEY_IS_NULL(keyCountryName);        auto countryName = keyCountryName->GetText();        if(countryName == nullptr)        {            return -1;        }        this->name = countryName;        auto keyProvince = keyCountry->FirstChildElement("province");        //反序列化std::vector<Province> vProvinces;        while(keyProvince != nullptr)        {                        auto keyProvinceName = keyProvince->FirstChildElement("name");            KEY_IS_NULL(keyProvinceName);            auto provinceName = keyProvinceName->GetText();            if(provinceName != nullptr)            {                Province province(provinceName);                auto keyCities = keyProvince->FirstChildElement("cities");                KEY_IS_NULL(keyCities);                auto keyCity = keyCities->FirstChildElement("city");                KEY_IS_NULL(keyCity);                //反序列化std::vector<City> vCities;                while(keyCity != nullptr)                {                    auto cityName = keyCity->GetText();                    if(cityName != nullptr)                    {                        City city(cityName);                        province.vCities.push_back(city);                    }                    //继续查找兄弟节点                    keyCity = keyCity->NextSiblingElement();                 }                this->vProvinces.push_back(province);            }            //继续查找兄弟节点            keyProvince = keyProvince->NextSiblingElement();        }        return 0;     }    //序列化对象到string    std::string toString()    {        std::string s;         if(!name.empty())        {            s+= "country name: ";            s+= name;        }        if(!vProvinces.empty())        {            for(auto province : vProvinces)            {                s+= " province name :";                s+= province.name;                if(!province.vCities.empty())                {                    s+= " city name: ";                    for(auto city : province.vCities)                    {                        s+= city.name;                        s+= " ";                    }                }            }        }        return s;    }};
test.cpp

#include <iostream>#include <string>#include <cstdlib>#include <vector>#include "../tinyxml2.h"#include "country.hpp"using namespace tinyxml2;using namespace std;#define EXIT_ABNOEMAL(msg) {printf("%s\n", msg); return -1;}//构造一个countryCountry* getCountry(const string &name){    auto country = new Country(name);    City haerbing("哈尔滨");    City daqing("大庆");    Province heilongjing("黑龙江");    heilongjing.vCities.push_back(haerbing);    heilongjing.vCities.push_back(daqing);    City guangzhou("广州");    City shenzhen("深圳");    City zhuhai("珠海");    Province guangdong("广东");    guangdong.vCities.push_back(guangzhou);    guangdong.vCities.push_back(shenzhen);    guangdong.vCities.push_back(zhuhai);    City taibei("台北");    City gaoxiong("高雄");    Province taiwan("台湾");    taiwan.vCities.push_back(gaoxiong);    taiwan.vCities.push_back(taibei);    City wulumuqi("乌鲁木齐");    Province xinjiang("新疆");    xinjiang.vCities.push_back(wulumuqi);        country->vProvinces.push_back(xinjiang);    country->vProvinces.push_back(heilongjing);    country->vProvinces.push_back(guangdong);    country->vProvinces.push_back(taiwan);        return country;}//序列化对象到xmlint parseCountryToXml(Country *country, const string &filePath){    XMLDocument doc;    //调用country的序列化函数    int ret = country->parseXML(doc, filePath);    return ret;}//反序列化到对象int readXMLToCountry(Country * country, const string &filePath){    XMLDocument doc;    //调用对象的反序列花方法    int ret = country->convertXMLToObject(doc, filePath);    return ret;}int main(){    const string fileName = "../test/country.xml";    //将中国对象保存到xml中    auto zhongguo = getCountry("zhongguo");    int ret;    ret = parseCountryToXml(zhongguo, fileName);    if(ret)    {        EXIT_ABNOEMAL("convert to xml error!");    }    //从上面的xml中反序列化成china对象    Country *china = new Country();    ret = readXMLToCountry(china, fileName);    if(ret)    {        EXIT_ABNOEMAL("convert to Object error!");    }    //输出china对象    string s = china->toString();    cout<<s<<"\n";    //安全删除指针    SAFE_DELETE(zhongguo);    SAFE_DELETE(china);    return 0;}

结果:

 country.xml

<?xml version="1.0" encoding="UTF-8"?><country>    <name>zhongguo</name>    <province>        <name>新疆</name>        <cities>            <city>乌鲁木齐</city>        </cities>    </province>    <province>        <name>黑龙江</name>        <cities>            <city>哈尔滨</city>            <city>大庆</city>        </cities>    </province>    <province>        <name>广东</name>        <cities>            <city>广州</city>            <city>深圳</city>            <city>珠海</city>        </cities>    </province>    <province>        <name>台湾</name>        <cities>            <city>高雄</city>            <city>台北</city>        </cities>    </province></country>


原创粉丝点击