游戏服务端之xml类型转换

来源:互联网 发布:最好吃的方便面知乎 编辑:程序博客网 时间:2024/06/05 11:35
上一篇博文我已经说明了服务端添加tinyxml的基本操作及基本用法。
我的服务端之添加xml解释器http://blog.csdn.net/yitouhan/article/details/17453159
但是可以看出tinyxml读出的数据是不做类型匹配的,也就是说tinyxml读出的数据都是字符串。但是在实际应用中,我还需要其它的数据类型,例如整型和浮点型。
实现类型转换的关键在istringstream,下面的链接有介绍

http://baike.baidu.com/link?url=t0pOzUA1bmDBQaHlCN4D7LjvF7ow9xryeCbcX5IP0SxsGfwEjPyZcIU37goGRTt-ccs3pKU1g4OrMdXgaN6Woq

#ifndef COMMONCONFIG_H#define COMMONCONFIG_H#include <string>#include <sstream>// 将字符串转成基础数据类型,非基础类型需显示定义template<class T>bool StringToBaseType(const std::string& str, T& val){std::istringstream stream;stream.str(str);if (stream>>val){return true;}return false;}// 将基础数据类型转成字符串,非基础类型需显示定义template<class T>bool BaseTypeToString(const T& src, std::string& tar){std::ostringstream stream;if (stream<<src){tar = stream.str();return true;}return false;}#include "tinyxml/tinyxml.h"template<class T>static bool GetSubNodeValue(TiXmlElement *element, const std::string& name, T& val){if (!element) return false;TiXmlElement *TmpElement = element->FirstChildElement(name.c_str());return GetNodeValue(TmpElement, val);}template<class T>static bool SetSubNodeValue(TiXmlElement *element, const std::string& name, T& val){if (!element) return false;TiXmlElement *TmpElement = element->FirstChildElement(name.c_str());return SetNodeValue(TmpElement, val);}// 读写如下节点element的值,不支持形如<element/>的空值// <element>s_val</element>template<class T>static bool GetNodeValue(TiXmlElement *element, T& val){if (!element || !element->FirstChild() || !StringToBaseType(element->GetText(), val)){return false;}return true;}class ConfigElementBase{public:ConfigElementBase():m_element(0) {}virtual ~ConfigElementBase() {}void SetElement(TiXmlElement *element) { m_element = element; }// 供子类列表中获取偏移地址virtual ConfigElementBase* offset() = 0;// 将子节点读到相应成员数据中virtual bool read() = 0;// 将成员数据写入文件virtual bool write() = 0;protected:// 获取子节点的值,不适用有多个同名子节点的情况template<class T>bool GetValue(const char *name, T* value){if (m_element == 0) return false;return GetSubNodeValue(m_element, name, *value);}bool GetValue(const char *name, ConfigElementBase* value){if (m_element == 0) return false;value->SetElement(m_element->FirstChildElement(name));return value->read();}// 获取子节点的值,适用有多个同名子节点的情况,与数组对应template<class T>bool GetListValue(const char *name, T* list_value, int& list_len, int list_max_len){list_len = 0;if (m_element == 0){return false;}TiXmlElement *tmp_element = m_element->FirstChildElement(name);for ( ;list_len < list_max_len && tmp_element != 0; ++list_len, ++list_value, tmp_element = tmp_element->NextSiblingElement(name)){if (!GetNodeValue(tmp_element, *list_value)) return false;}return true;}bool GetListValue(const char *name, ConfigElementBase* list_value, int& list_len, int list_max_len){list_len = 0;if (m_element == 0){return false;}TiXmlElement *tmp_element = m_element->FirstChildElement(name);for ( ;list_len < list_max_len && tmp_element != 0; ++list_len){list_value->SetElement(tmp_element);if (!list_value->read())return false;list_value = list_value->offset();tmp_element = tmp_element->NextSiblingElement(name);}return true;}// 设置子节点的值,不适用有多个同名子节点的情况template<class T>bool SetValue(const char *name, T* value){if (m_element == 0) return false;TiXmlElement * tmp_element = m_element->FirstChildElement(name);if (!tmp_element){TiXmlElement insert_node(name);tmp_element = (TiXmlElement *)m_element->InsertEndChild(insert_node);}if (!tmp_element->FirstChild()){std::string tmp_value;BaseTypeToString(*value, tmp_value);TiXmlText sub_node(tmp_value);tmp_element->InsertEndChild(sub_node);return true;}return SetSubNodeValue(m_element, name, *value);}bool SetValue(const char *name, ConfigElementBase* value){if (m_element == 0) return false;TiXmlElement * tmp_element = m_element->FirstChildElement(name);if (!tmp_element){TiXmlElement insert_node(name);m_element->InsertEndChild(insert_node);tmp_element = m_element->FirstChildElement(name);}value->SetElement(tmp_element);return value->write();}// 设置子节点的值,适用有多个同名子节点的情况,与数组对应template<class T>bool SetListValue(const char *name, T* list_value, int list_len){if (m_element == 0 || list_len < 0){return false;}TiXmlElement *tmp_element = m_element->FirstChildElement(name);for(int i=0;i<list_len;++i,++list_value){if (!tmp_element){TiXmlElement insert_node(name);tmp_element = (TiXmlElement *)m_element->InsertEndChild(insert_node);}if (!tmp_element->FirstChild()){std::string tmp_value;BaseTypeToString(*list_value, tmp_value);TiXmlText sub_node(tmp_value);tmp_element->InsertEndChild(sub_node);}else{if (!SetNodeValue(tmp_element, *list_value)) return false;}tmp_element = tmp_element->NextSiblingElement(name);}while(tmp_element){TiXmlElement *to_remove = tmp_element;tmp_element = tmp_element->NextSiblingElement(name);m_element->RemoveChild(to_remove);};return true;}bool SetListValue(const char *name, ConfigElementBase* list_value, int list_len){if (m_element == 0 || list_len < 0){return false;}TiXmlElement *tmp_element = m_element->FirstChildElement(name);for(int i=0;i<list_len;++i){if (!tmp_element){TiXmlElement insert_node(name);tmp_element = (TiXmlElement *)m_element->InsertEndChild(insert_node);}list_value->SetElement(tmp_element);if (!list_value->write()) return false;list_value= list_value->offset();tmp_element = tmp_element->NextSiblingElement(name);}while(tmp_element){TiXmlElement *to_remove = tmp_element;tmp_element = tmp_element->NextSiblingElement(name);m_element->RemoveChild(to_remove);};return true;}// 至少有一个节点的xml结构TiXmlElement *m_element;private:};#endif
下面是测试用例
<?xml version="1.0" encoding="utf-8"?><blog>  <blogger>一头汗</blogger><date>20131221</date><temperature>10.1</temperature></blog> 
#include <stdio.h>#include <time.h>#include "globalvariable.h"#include "luaengine.h"#include "gamesocket.h"#include "log.h"#include "dll.h"#include "MyDll.h"#include "gametime.h"#include "frame.h"#include "datatable.h"#include "showcrash.h"#include "globalfunction.h"#include "commonconfig.h"void Init(){    TiXmlDocument doc;    if (doc.LoadFile("conf/info.xml"))    {        TiXmlElement* rootElement = doc.RootElement();        if (rootElement == NULL)        {            return ;        }        char blogger[16]={0};        GetSubNodeValue(rootElement, "blogger",blogger);        printf("博主:%s\n", blogger);        int date = 0;        GetSubNodeValue(rootElement, "date",date);        printf("日期:%d\n", date);        float temperature = 0.0;        GetSubNodeValue(rootElement,  "temperature", temperature);        printf("温度:%f\n", temperature);    }}int main(){    Init();    return 0;}
输出结果:


5 0
原创粉丝点击