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

之前一直都是采用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. [深圳/广州]微软SQL技术沙龙分享会(MVP)

    [深圳/广州] 新一期俱乐部活动报名开始,这次是广深地区SQL Server 技术沙龙分享会(MVP),SQL Server作为一个数据平台,不管是SQL Server 2017 on Linux 还 ...

  2. c++概括

    c++到底是什么样的语言 在过去的几十年,计算机技术的发展令人吃惊,当前的笔记本电脑的计算速度和存储信息的能力超过了20世纪60年代的大型机.20世纪七十年代,C和Pascal语言引领人们进入结构化编 ...

  3. WEB前端:浏览器(IE+Chrome+Firefox)常见兼容问题处理--01

    兼容问题目录 1.IE6下怪异盒模型 2.IE6下最小高度问题 3.IE6下不支持1px的点线 4.IE6下内容会把父级的高度撑开 5.IE6下只支持给a标签添加伪类 6.IE67下不支持给块标签加d ...

  4. vue使用Axios做ajax请求

    vue2.0之后,就不再对vue-resource更新,而是推荐使用axios 1. 安装 axios $ npm install axios 或 $ bower install axios 2. 在 ...

  5. JSP手动注入 全

    检测可否注入 http://****.house.sina.com.cn/publics/detail.jsp?id=7674 and 1=1 (正常页面) http://****.house.sin ...

  6. oracle日期时间函数 总结

    表中存在伪列:sysdate,systimestamp 伪列存在但是不显示 select sysdate from dual; select systimestamp from dual; 日期计算公 ...

  7. Layered Windows窗口的半透明效果

    介绍: Layered Windows是windows窗口中的一类,提供类似半透明的效果(阿尔法混合).半透明效果是字面上有能看出来的,但实际上根据MSND,该类型的窗口还能更好的支持非矩形的窗口,使 ...

  8. 执行ANT JAVA三种方式

    1. 命令行 <target name="reporttoexcel" depends="report"> <exec executable= ...

  9. 关于getHTML()方法和getHtmlAjax()方法 GetHttpLength, 清除HTML标签

    public string getHtml(string Url, string type = "UTF-8") { try { System.Net.WebRequest wRe ...

  10. php添加pcntl扩展(Linux)

    pcntl扩展可以支持php的多线程操作(仅限linux)原本需要重新编译PHP的后面configrue提示加上--enable-pcntl 由于我的php是采用yum安装的,所以不能采用上面的方式下 ...