做服务器肯定会涉及到游戏配表,而读取游戏配表是一个必备技能;

之前一直都是采用TinyXml直接读,匹配字符串,每次加个表都是一大坨代码,看着也是心累;

因此利用了闲暇的时间封装了一个 xml配置表 读取类;

1.支持 按照 列*行的读取方法

2.支持 按照 "标题"*行的读取方法

3.支持 按照 列*行的修改

4.支持 按照 "标题"*行的修改

//例子用的xml , 库用的是 tinyxml 2.5.3

<?xml version="1.0" encoding="gbk" standalone="yes" ?>
<config>
<Quest Quest_ID="1" Quest_Star="1" Quest_Limit="0" Quest_Type="6" Quest_TarID="0" Quest_Tar_Num="100" Award_Type="2" Award_ID="1" Awa_Num="5000" Quest_Des="击杀%d" bModify="0" bNew="0" />
<Quest Quest_ID="2" Quest_Star="1" Quest_Limit="0" Quest_Type="6" Quest_TarID="0" Quest_Tar_Num="500" Award_Type="2" Award_ID="1" Awa_Num="10000" Quest_Des="击杀%d" bModify="0" bNew="0" />
<Quest Quest_ID="3" Quest_Star="1" Quest_Limit="0" Quest_Type="10" Quest_TarID="0" Quest_Tar_Num="3" Award_Type="2" Award_ID="1" Awa_Num="6000" Quest_Des="击杀%d" bModify="0" bNew="0" />
<Quest Quest_ID="4" Quest_Star="1" Quest_Limit="0" Quest_Type="10" Quest_TarID="0" Quest_Tar_Num="5" Award_Type="2" Award_ID="1" Awa_Num="8000" Quest_Des="击杀%d" bModify="0" bNew="0" />
<Quest Quest_ID="5" Quest_Star="1" Quest_Limit="0" Quest_Type="11" Quest_TarID="0" Quest_Tar_Num="1" Award_Type="2" Award_ID="1" Awa_Num="10000" Quest_Des="击杀%dBOSS" bModify="0" bNew="0" />
<Quest Quest_ID="6" Quest_Star="1" Quest_Limit="0" Quest_Type="11" Quest_TarID="0" Quest_Tar_Num="2" Award_Type="2" Award_ID="1" Awa_Num="15000" Quest_Des="击杀%dBOSS" bModify="0" bNew="0" />
<Quest Quest_ID="7" Quest_Star="1" Quest_Limit="0" Quest_Type="6" Quest_TarID="0" Quest_Tar_Num="100" Award_Type="2" Award_ID="2" Awa_Num="10" Quest_Des="击杀%d" bModify="0" bNew="0" />
<Quest Quest_ID="8" Quest_Star="1" Quest_Limit="0" Quest_Type="6" Quest_TarID="0" Quest_Tar_Num="500" Award_Type="2" Award_ID="2" Awa_Num="25" Quest_Des="击杀%d" bModify="0" bNew="0" />
<Quest Quest_ID="9" Quest_Star="1" Quest_Limit="0" Quest_Type="10" Quest_TarID="0" Quest_Tar_Num="3" Award_Type="2" Award_ID="2" Awa_Num="15" Quest_Des="击杀%d赏金" bModify="0" bNew="0" />
<Quest Quest_ID="10" Quest_Star="1" Quest_Limit="0" Quest_Type="10" Quest_TarID="0" Quest_Tar_Num="5" Award_Type="2" Award_ID="2" Awa_Num="20" Quest_Des="击杀%d赏金" bModify="0" bNew="0" />
<Quest Quest_ID="11" Quest_Star="1" Quest_Limit="0" Quest_Type="11" Quest_TarID="0" Quest_Tar_Num="1" Award_Type="2" Award_ID="2" Awa_Num="25" Quest_Des="击杀%d" bModify="0" bNew="0" />
<Quest Quest_ID="12" Quest_Star="1" Quest_Limit="0" Quest_Type="11" Quest_TarID="0" Quest_Tar_Num="2" Award_Type="2" Award_ID="2" Awa_Num="40" Quest_Des="击杀%d" bModify="0" bNew="0" />
</config>

下面就直接上代码;

#pragma once
#pragma warning(disable:4786)
#pragma warning(disable:4503) #include "tinyxml.h"
#include <map>
#include <string> using namespace std;
class CRowStr{
public:
CRowStr(int row,string title)
{
_row=row;
_title=title;
} bool operator<( const CRowStr& a) const
{
if(this->_row<a._row)
return true;
else
return false;
}; int _row;//行
string _title;//标题
}; typedef map<CRowStr, string> mpCfgRow;
typedef map<int, mpCfgRow*> mpCfgList; //默认从第1列开始读取
#define ROWBEGIN 1 //默认从第1行开始读取
#define LINEBEGIN 1 //非元素模式从1000开始
#define NEXTBEGIN 1000 //暂时不支持非元素模式
class CXmlFileReader
{
public:
CXmlFileReader(const char* _filename,const int _flag=1);
~CXmlFileReader(); //获取第line行的_title字段的数据
char* GetValueByTitle(const char*_title/*字段*/, const int _line=LINEBEGIN/*行数*/);
//获取第line行的_row列数据
char* GetValueByRow(const int _row=ROWBEGIN/*列数*/, const int _line=LINEBEGIN/*行数*/); //设置第line行的_title字段的数据
bool SetValueByTitle(const char *_value/*内容*/,const char*_title/*字段*/,const int _line=LINEBEGIN/*行数*/);
//设置第line行的_row列数据
bool SetValueByRow(const char *_value/*内容*/,const int _row=ROWBEGIN/*列数*/,const int _line=LINEBEGIN/*行数*/); int GetLines();//获取行数
int GetRows();//获取列数 private:
void _loadFile();
void _clearMap();
void _example();//例子 private:
bool m_load_ok;
string m_path;
int m_Flag;
int m_Maxlines;
int m_Maxrows;
mpCfgList* m_config_map;
};

下面是.cpp文件

#include "XmlControl.h"

CXmlFileReader::CXmlFileReader(const char* _filename,const int _flag)
{
m_Maxlines=0;
m_Maxrows=0;
m_config_map = new mpCfgList;
m_path = string(_filename);
m_Flag = _flag;
_loadFile();
} CXmlFileReader::~CXmlFileReader()
{
_clearMap();
} void CXmlFileReader::_example()
{
//用法
string filePath = "D:\\Quest.xml";
CXmlFileReader Reader(filePath.c_str()); //读取
string _desRowOld(Reader.GetValueByRow(10,2));
string _desTitleOld(Reader.GetValueByTitle("Quest_Des",3));
//设置节点值
Reader.SetValueByTitle("Testtitle","Quest_Des",3);
Reader.SetValueByRow("Testrow",10,2);
//读取
string _desRowNew(Reader.GetValueByRow(10,2));
string _desTitleNew(Reader.GetValueByTitle("Quest_Des",3));
} int CXmlFileReader::GetLines()
{
if(!m_load_ok)
return 0;
return m_Maxlines;
} int CXmlFileReader::GetRows()
{
if(!m_load_ok)
return 0;
return m_Maxrows;
} char* CXmlFileReader::GetValueByTitle(const char* title,const int line)
{
if (!m_load_ok)
return NULL;
char* value = NULL;
mpCfgList::iterator itLine = m_config_map->find(line);
if(itLine == m_config_map->end())
return NULL;
mpCfgRow* mpRowValue = itLine->second;
mpCfgRow::iterator itValue = mpRowValue->begin();
for (; itValue != mpRowValue->end(); itValue++){
const CRowStr key=itValue->first;
if (key._title==string(title)){
value = (char*) itValue->second.c_str();
break;
}
}
return value;
} char* CXmlFileReader::GetValueByRow(const int row, const int line)
{
if (!m_load_ok)
return NULL;
char* value = NULL;
mpCfgList::iterator itLine = m_config_map->find(line);
if(itLine == m_config_map->end())
return NULL;
mpCfgRow* mpRowValue = itLine->second;
mpCfgRow::iterator itValue = mpRowValue->begin();
for (; itValue != mpRowValue->end(); itValue++){
const CRowStr key = itValue->first;
if(key._row == row){
value = (char*) itValue->second.c_str();
break;
}
}
return value;
} bool CXmlFileReader::SetValueByTitle(const char * value,const char* title,const int line)
{
TiXmlDocument _doc;
int _curline=line;
int _flag = m_Flag;
if(!_doc.LoadFile(m_path.c_str())||!title||!value)
return false;
//改xml值
TiXmlElement* _pelement = _doc.RootElement(); //root
while(_flag--){
_pelement = _pelement->FirstChildElement(); //指向下一个
}
while(_pelement){
TiXmlAttribute* _attributeOfStudent = _pelement->FirstAttribute(); //获得每一级的各种属性
if(--_curline>0){
_pelement = _pelement->NextSiblingElement();
continue;
}
while(_attributeOfStudent){
if(string(_attributeOfStudent->Name())==title){
_attributeOfStudent->SetValue(value);
break;
}
_attributeOfStudent = _attributeOfStudent->Next();//指向下一个元素
}
break;
}
//保存
if(!_doc.SaveFile(m_path.c_str()))
return false; //改内存里的值
mpCfgList::iterator itLine = m_config_map->find(line);
if(itLine == m_config_map->end())
return NULL;
mpCfgRow* mpRowValue = itLine->second;
mpCfgRow::iterator itValue = mpRowValue->begin();
for (; itValue != mpRowValue->end(); itValue++){
const CRowStr key = itValue->first;
string _strtile = string(title);
if (key._title==_strtile){
string _newValue = string(value);
itValue->second = _newValue;
break;
}
}
return true;
} bool CXmlFileReader::SetValueByRow(const char * value,const int row,const int line)
{
TiXmlDocument _doc;
int _curline=line;
int _currow=row;
int _flag = m_Flag;
if(!_doc.LoadFile(m_path.c_str())||!value)
return false;
//改xml值
TiXmlElement* _pelement = _doc.RootElement();
while(_flag--){
_pelement = _pelement->FirstChildElement();
}
while(_pelement){
TiXmlAttribute* _attributeOfStudent = _pelement->FirstAttribute();
if(--_curline>0){
_pelement = _pelement->NextSiblingElement();
continue;
}
while(_attributeOfStudent){
if(--_currow>0){
_attributeOfStudent = _attributeOfStudent->Next();
continue;
}
_attributeOfStudent->SetValue(value);
break;
}
break;
}
//保存
if(!_doc.SaveFile(m_path.c_str()))
return false; //改内存里的值
mpCfgList::iterator itLine = m_config_map->find(line);
if(itLine == m_config_map->end())
return NULL;
mpCfgRow* mpRowValue = itLine->second;
mpCfgRow::iterator itValue = mpRowValue->begin();
for (; itValue != mpRowValue->end(); itValue++){
const CRowStr key = itValue->first;
if(key._row==row){
string _newValue = string(value);
itValue->second = _newValue;
break;
}
}
return true;
} void CXmlFileReader::_clearMap()
{
if(!m_config_map)
return;
mpCfgList::iterator it = m_config_map->begin();
for (; it != m_config_map->end(); it++){
delete it->second;
} delete m_config_map;
m_config_map = NULL;
} void CXmlFileReader::_loadFile()
{
int _flag = m_Flag;
TiXmlDocument _doc;
int _line=LINEBEGIN;
//int _nxline=NEXTBEGIN;
int _row=ROWBEGIN;
if(!_doc.LoadFile(m_path.c_str())){
m_load_ok=false;
return;
}
TiXmlElement* _pelement=_doc.RootElement(); //root
while(_flag--){
_pelement=_pelement->FirstChildElement();//指向下一个大节点
}
switch (_pelement->Type())
{
case TiXmlText::DOCUMENT:break;
case TiXmlText::DECLARATION:break;
case TiXmlText::TEXT:break;
case TiXmlText::UNKNOWN:break;
case TiXmlText::COMMENT:break;
case TiXmlText::ELEMENT:
{
while(_pelement){
TiXmlAttribute* _attributeOfStudent=_pelement->FirstAttribute(); //获得每一级的各种属性
if (_attributeOfStudent)
{
mpCfgRow* mpRowValue= new mpCfgRow();
int _rowdex=ROWBEGIN;
while (_attributeOfStudent){
CRowStr _rowinfo(_rowdex++,string(_attributeOfStudent->Name()));
mpRowValue->insert(make_pair(_rowinfo,string(_attributeOfStudent->Value())));//存储第_line行的所有列
_attributeOfStudent=_attributeOfStudent->Next();//指向下一个元素
++_row;
}
_pelement=_pelement->NextSiblingElement();
m_config_map->insert(make_pair(_line++,mpRowValue));//存储_line行的所有元素
}
else
{
/*mpCfgRow* mpRowValue= new mpCfgRow();
mpRowValue->insert(make_pair(string(_pelement->Value()),
string(_pelement->FirstChild()->Value())));//存储第_line行的所有列
_pelement=_pelement->NextSiblingElement();
m_config_map->insert(make_pair(_nxline++,mpRowValue));//存储_line行的所有元素
*/
} }
m_Maxlines=_line-LINEBEGIN;
m_Maxrows=(_row-ROWBEGIN)/m_Maxlines;
m_load_ok=true;
}
break;
}
}

封装游戏配表读取和存储(xml格式);支持行列存取,标题存取的更多相关文章

  1. 用Ajax去读取服务器端的XML格式的数据

    <html> <head></head> <script type="text/javascript"> /*---定义一个全局变量 ...

  2. 在文件中读取、存储Json格式的字符串

    public class Weather { static readonly string FilePath = System.Environment.CurrentDirectory + @&quo ...

  3. C#操作数据表中XML格式的数据

    以前还真没有见过数据表中存储XML格式的数据,刚开始听说的时候,还以为是数据表中有XML的字段类型, 再了解,其实也就是字符串类型的,只不过字符串的格式是XML格式的.确实孤陋寡闻!汗... (可添加 ...

  4. Spring MVC同一方法返回JSON/XML格式

    最近一道面试题,要求同一API接口支持不同格式返回值.一开始是设想通过过滤器(Filter)设置返回值,但是并不可行,因为方法返回值一般都是类型需要做转换,而过滤器则是前置的.另一方面可以通过拦截器的 ...

  5. Android:Xml(读取与存储)

    1.读取XML文件 参数xml是建含xml数据的输入流,List<Person> persons用于存储xml流中的数据. XmlPullParser类的几个方法:next(),nextT ...

  6. hive 压缩全解读(hive表存储格式以及外部表直接加载压缩格式数据);HADOOP存储数据压缩方案对比(LZO,gz,ORC)

    数据做压缩和解压缩会增加CPU的开销,但可以最大程度的减少文件所需的磁盘空间和网络I/O的开销,所以最好对那些I/O密集型的作业使用数据压缩,cpu密集型,使用压缩反而会降低性能. 而hive中间结果 ...

  7. .net数据库连接防注入参数查询 命令执行 读取 备份 导出导入转化XML格式

    ADO.NET是一组类库,让我们通过程序的方式访问数据库.SYSTEM.DATA这个类提供了统一的接口访问Oracle MSSQL Access.像SYSTEM.IO类操作文件一样. **connec ...

  8. Java读取CSV和XML文件方法

    游戏开发中,读取策划给的配置表是必不可少的,我在之前公司,策划给的是xml表来读取,现在公司策划给的是CSV表来读取,其实大同小异,也并不是什么难点,我就简单分享下Java如何读取XML文件和CSV文 ...

  9. Delphi 读取 c# webservice XML的base64编码图片字符串转化图片并显示

    Delphi 读取 c# webservice XML的base64编码图片字符串转化图片并显示 在 开发中遇到应用c#及asp.net的在的webservice 保存图片并以xml文件形式现实出来 ...

随机推荐

  1. Syntax error on tokens, delete these tokens.问题解决

    问题:Syntax error on tokens, delete these tokens.(在标记语法错误,删除这些标记) 原因:存在中文字符或者符号(包括空格):单引号.双引号不匹配:复制的代码 ...

  2. selenium+python等待时间

    等待时间可以有多种 1.硬等待 import time time.sleep(x)#等待x秒 2.浏览器每次查找一个元素都进行等待 import time br.implicitly_wait(x)# ...

  3. DISCUZ积分及点评需求

    1.点评设置(可增强用户互动,但又不会顶帖刷屏):目前很难限制用户通过点评刷积分,点评等同于回复但却不需要审核,目前只是简单地关闭了点评功能.需求:可以审核点评内容:可以限制点评不获得积分或每天点评获 ...

  4. ZooKeeper数据模型

    ZooKeeper有一个分层的命名空间,类似分布式文件系统.它们唯一的区别就在于在命名空间中每个节点可以有数据关联作为它们的子节点.这就像有一个文件系统允许文件也作为文件目录.节点路径通常表示为规范的 ...

  5. rem的js

    html { font-size : 20px; } @media only screen and (min-width: 401px){ html { font-size: 25px !import ...

  6. Ruby中文乱码问题

    中文乱码问题 解决方法为只要在文件开头加入 # -*- coding: UTF-8 -*-(EMAC写法) 或者 #coding=utf-8 就行了. 源代码文件中,若包含中文编码,则需要注意两点: ...

  7. 实现简易版的moment.js

    github源码地址: www.baidu.com 作者: 易怜白 项目中使用了时间日期的处理方法,只使用了部分方法,为了不在引入第三方的库(moment.js),这里自己封装了项目中使用到的方法. ...

  8. 谈谈java中遍历Map的几种方法

    java中的map遍历有多种方法,从最早的Iterator,到java5支持的foreach,再到java8 Lambda,让我们一起来看下具体的用法以及各自的优缺点 先初始化一个map public ...

  9. jquery 检测某元素是否含有某属性

    检测某元素是否含有某属性 if(typeof($("#aid").attr("rel"))=="undefined")

  10. 无法为具有固定名称“MySql.Data.MySqlClient”的 ADO.NET 提供程序加载在应用程序配置文件中注册的实体框架提供程序类型“MySql.Data.MySqlClient.MySqlProviderServices,MySql.Data.Entity.EF6”

    "System.InvalidOperationException"类型的未经处理的异常在 mscorlib.dll 中发生 其他信息: 无法为具有固定名称"MySql. ...