封装游戏配表读取和存储(xml格式);支持行列存取,标题存取
做服务器肯定会涉及到游戏配表,而读取游戏配表是一个必备技能;
之前一直都是采用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格式);支持行列存取,标题存取的更多相关文章
- 用Ajax去读取服务器端的XML格式的数据
<html> <head></head> <script type="text/javascript"> /*---定义一个全局变量 ...
- 在文件中读取、存储Json格式的字符串
public class Weather { static readonly string FilePath = System.Environment.CurrentDirectory + @&quo ...
- C#操作数据表中XML格式的数据
以前还真没有见过数据表中存储XML格式的数据,刚开始听说的时候,还以为是数据表中有XML的字段类型, 再了解,其实也就是字符串类型的,只不过字符串的格式是XML格式的.确实孤陋寡闻!汗... (可添加 ...
- Spring MVC同一方法返回JSON/XML格式
最近一道面试题,要求同一API接口支持不同格式返回值.一开始是设想通过过滤器(Filter)设置返回值,但是并不可行,因为方法返回值一般都是类型需要做转换,而过滤器则是前置的.另一方面可以通过拦截器的 ...
- Android:Xml(读取与存储)
1.读取XML文件 参数xml是建含xml数据的输入流,List<Person> persons用于存储xml流中的数据. XmlPullParser类的几个方法:next(),nextT ...
- hive 压缩全解读(hive表存储格式以及外部表直接加载压缩格式数据);HADOOP存储数据压缩方案对比(LZO,gz,ORC)
数据做压缩和解压缩会增加CPU的开销,但可以最大程度的减少文件所需的磁盘空间和网络I/O的开销,所以最好对那些I/O密集型的作业使用数据压缩,cpu密集型,使用压缩反而会降低性能. 而hive中间结果 ...
- .net数据库连接防注入参数查询 命令执行 读取 备份 导出导入转化XML格式
ADO.NET是一组类库,让我们通过程序的方式访问数据库.SYSTEM.DATA这个类提供了统一的接口访问Oracle MSSQL Access.像SYSTEM.IO类操作文件一样. **connec ...
- Java读取CSV和XML文件方法
游戏开发中,读取策划给的配置表是必不可少的,我在之前公司,策划给的是xml表来读取,现在公司策划给的是CSV表来读取,其实大同小异,也并不是什么难点,我就简单分享下Java如何读取XML文件和CSV文 ...
- Delphi 读取 c# webservice XML的base64编码图片字符串转化图片并显示
Delphi 读取 c# webservice XML的base64编码图片字符串转化图片并显示 在 开发中遇到应用c#及asp.net的在的webservice 保存图片并以xml文件形式现实出来 ...
随机推荐
- jquery中html、text、val回调函数
先扫盲: 摘自菜鸟教程:jQuery 方法:text().html() 以及 val()拥有回调函数. 回调函数有两个参数:被选元素列表中当前元素的下标,以及原始(旧的)值.然后以函数新值返回您希望使 ...
- 一天搞定HTML----标签的嵌套规则06
标签的嵌套规则 代码演示 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...
- 网络编程应用:基于UDP协议【实现文件下载】--练习
要求: 基于UDP协议实现文件下载 发送方–请求–接收方发送文件–发送方接收文件 代码: 发送方: package Homework1; import java.io.File; import jav ...
- myBatis动态语句详解
SQL 映射XML 文件是所有sql语句放置的地方.需要定义一个workspace,一般定义为对应的接口类的路径.写好SQL语句映射文件后,需要在MyBAtis配置文件mappers标签中引用,例如: ...
- Vulkan Tutorial 17 Rendering and presentation
操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 Setup 这一章节会把之前的所有内容进行整合.我们将会编写drawFrame函数, ...
- [转] 传说中的WCF
这个解决方案中包含两个项目,一个叫Server,另一个叫Client,天生一对. 1.启动VS 2010,推荐用2010以上版本(2012 RC版也行),因为越高版本越好用,最好Express的,不要 ...
- dubbo的简单应用
一. dubbo简介 dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴SOA服务化治理方案的核心框架. 二. 架构 引用dubbo的架构图: Provide ...
- 为Windows资源管理器右键菜单添加菜单项
为Windows资源管理器右键菜单添加菜单项 在Windows下命令行用的比较多,经常在资源管理器里翻到某个目录,若想要在此目录下跑命令,只能是打开cmd.exe,然后一路cd才能到达此目录. 每次都 ...
- 如何在非 React 项目中使用 Redux
本文作者:胡子大哈 原文链接:https://scriptoj.com/topic/178/如何在非-react-项目中使用-redux 转载请注明出处,保留原文链接和作者信息. 目录 1.前言 2. ...
- 用window的onload事件,窗体加载完毕的时候
<script type="text/javascript"> //用window的onload事件,窗体加载完毕的时候 window.onload=function( ...