码迷,mamicode.com
首页 > 其他好文 > 详细

读xml生成代码例子

时间:2015-02-04 23:27:37      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:

读xml生成相应的  lua解析协议代码

#include <iostream>
#include "tinyxml2.h"
#include <fstream>
#include <string>

using namespace tinyxml2;
using namespace std;
std::ofstream file("readProto.lua",std::ios::ate|std::ios::binary);

void read_S_ElementChild(XMLElement *surface)
{
	while (surface)
	{
		const XMLAttribute *attr = surface->FirstAttribute();//获取第一个属性值
		string strType;
		bool isArray = false;
		while(attr)
		{
			if (strcmp(attr->Name(), "name")==0)
			{
				string name = attr->Value();
				string dataStr = "data.";
				string temp1 = "\t" + dataStr + name + " = ";
				string temp;
				if(strcmp(strType.c_str(), "String")==0){
					temp =  "is:readUTF8()";
				}else if(strcmp(strType.c_str(), "long")==0){
					temp = "is:readLong()";
				}else if(strcmp(strType.c_str(), "int")==0){
					temp = "is:readInt()";
				}else if(strcmp(strType.c_str(), "short")==0){
					temp = "is:readShort()";
				}else if(strcmp(strType.c_str(), "byte")==0){
					temp = "is:readByte()";
				}else if(strcmp(strType.c_str(), "boolean")==0){
					temp = "is:readBool()";
				}else if(strcmp(strType.c_str(), "float")==0){
					temp = "is:readJavaFloat()";
				}else{
					size_t len = strType.size();
					string lastStr = strType.substr(len-2, 2);
					if(strcmp(lastStr.c_str(), "[]")==0){ //代表是数组
						isArray	= true;
						file << "\tlocal cnt = is:readShort()" << endl;
						file << "\tlocal temps = {}" << endl;
						file << "\tfor i=1, cnt do" << endl;
						string preStr = strType.substr(0, len-2);
						string preStrTemp;
						if(strcmp(preStr.c_str(), "String")==0){
							preStrTemp =  "is:readUTF8()";
						}else if(strcmp(preStr.c_str(), "long")==0){
							preStrTemp = "is:readLong()";
						}else if(strcmp(preStr.c_str(), "int")==0){
							preStrTemp = "is:readInt()";
						}else if(strcmp(preStr.c_str(), "short")==0){
							preStrTemp = "is:readShort()";
						}else if(strcmp(preStr.c_str(), "byte")==0){
							preStrTemp = "is:readByte()";
						}else if(strcmp(preStr.c_str(), "boolean")==0){
							preStrTemp = "is:readBool()";
						}else if(strcmp(preStr.c_str(), "float")==0){
							preStrTemp = "is:readJavaFloat()";
						}else
						{
							preStrTemp = "read_" + preStr + "(is)";
						}
						file << "\t\ttemps[i] = " << preStrTemp << endl;
						file << "\tend" << endl;
					}else{
						temp = "read_" + strType + "(is)";
					}
				}
				if(!isArray){
					file << temp1 + temp;
				}else{ //是数组
					file << temp1 + "temps" ;
				}
			}else if(strcmp(attr->Name(), "type")==0)
			{
				strType = attr->Value();
				
			}else if(strcmp(attr->Name(), "description")==0)
			{
				string desc = attr->Value();
				string temp = "  --" + desc;
				file << temp << endl;
				if(isArray)
				{
					file << endl;
				}
			}
			attr = attr->Next(); //获取下一个属性值
		}
		surface = surface->NextSiblingElement();//当前对象的下一个节点
	}
}

void read_C_ElementChild(XMLElement *surface)
{
	int i = 0;
	while (surface)
	{
		string strType;
		const XMLAttribute *attr = surface->FirstAttribute();//获取第一个属性值
		while(attr)
		{
			if (strcmp(attr->Name(), "name")==0)
			{
				string temp;
				bool isNum = false;
				string param = "param";
				char num[4]="";
				sprintf_s(num, "%d", i);
				
				if(strcmp(strType.c_str(), "String")==0){
					temp = "sendData:writeUTF8(";
				}else if(strcmp(strType.c_str(), "long")==0){
					isNum = true;
					temp = "sendData:writeLong(";
				}else if(strcmp(strType.c_str(), "int")==0){
					isNum = true;
					temp = "sendData:writeInt(";
				}else if(strcmp(strType.c_str(), "short")==0){
					isNum = true;
					temp = "sendData:writeShort(";
				}else if(strcmp(strType.c_str(), "byte")==0){
					isNum = true;
					temp = "sendData:writeByte(";
				}else if(strcmp(strType.c_str(), "boolean")==0){
					temp = "sendData:writeBool(";
				}else if(strcmp(strType.c_str(), "float")==0){
					isNum = true;
					temp = "sendData:writeJavaFloat(";
				}else{

					temp = "error ############ ";
				}

				if (isNum)
				{
					file << "\tlocal " + param + num + " = tonumber(" + "self:getExtraValue("  + num + "))" << endl;
				}else{
					file << "\tlocal " + param + num + " = " + "self:getExtraValue("  + num + ")" << endl;
				}
				file << "\t" + temp + param + num + ")" ;
			}else if(strcmp(attr->Name(), "type")==0){
				strType = attr->Value();
			}else if(strcmp(attr->Name(), "description")==0){
				file << "  --" << attr->Value() << endl;
			}
			
			attr = attr->Next(); //获取下一个属性值
		}
		i = i + 1;
		surface = surface->NextSiblingElement();//当前对象的下一个节点
	}
}

void read_xml(XMLElement *surface)
{
	while (surface)
	{
		string id;
		string name;
		bool isRead = true;
		const XMLAttribute *attr = surface->FirstAttribute();//获取第一个属性值
		while(attr)
		{
			if(strcmp(attr->Name(), "id")==0)
			{
				id = attr->Value();
			}else if(strcmp(attr->Name(), "name")==0)
			{
				name = attr->Value();
				string fristStr = name.substr(0,1);
				string wirteStr = "function read_" + name + "(is)";
				if(strcmp(fristStr.c_str(), "C")== 0 )
				{
					isRead = false;
					wirteStr = "function send_" + name + "(self)";
				}
				file << wirteStr ;
			}else if(strcmp(attr->Name(), "description")==0)
			{
				file << "  --" << attr->Value() << endl;
				if (!isRead)
				{
					file << "\tlocal " + name + " = " + id + "  --" + attr->Value() << endl;
					file << "\tlocal sendData = ByteArrayOutputStream()" << endl;
					file << "\tsendData:writeInt(" + id + ")" << endl;
				}
			}
			attr = attr->Next(); //获取下一个属性值
		}

		XMLElement *surface1 = surface->FirstChildElement(); //查看当前对象是否有子节点
		if(surface1)
		{
			if(isRead)
			{
				file << "\tlocal data = {}" << endl;
				read_S_ElementChild(surface1);//递归调用
			}else
			{
				read_C_ElementChild(surface1);
			}
		}
		if (isRead)
		{
			file << "\treturn data" << endl;
		}else
		{
			file << "\tsendDataStream(sendData)" << endl;
		}
		file << "end"  << endl;
		file << endl;
		surface = surface->NextSiblingElement();//当前对象的下一个节点
	}
}

int main()
{
	if(!file)
    {
        std::cout<<"文件打开失败!";
        abort();//等同于exit
    }
	tinyxml2::XMLDocument mydocument; //声明xml对象
	mydocument.LoadFile("protocol.xml"); //载入xml文件
	XMLElement *rootElement = mydocument.RootElement(); //获取跟节点
	XMLElement *surface = rootElement->FirstChildElement("message");//获取第一个值为value的子节点 默认为空则返回第一个节点
	read_xml(surface);
	file.close();
	cin.get();
}


xml

	<message id="0x09001017" name="S_ITEM_ADD_TASK" description="向背包添加一种任务道具">
		<field type="int" name="task_max" description="任务道具包裹的当前长度(可能有空格)"/>
		<field type="S_ITEM_TASKPROPS[]" name="items" description="数据"/>
	</message>

	<message id="0x02000006" name="C_MAP_NODE_ARRIVE" description="角色到达结点">
		<field type="int" name="id" description="关卡结点id"/>
		<field type="boolean" name="isEnd" description="是否到达终点"/>
	</message>

生成效果:

lua

function read_S_ITEM_ADD_TASK(is)  --向背包添加一种任务道具
	local data = {}
	data.task_max = is:readInt()  --任务道具包裹的当前长度(可能有空格)
	local cnt = is:readShort()
	local temps = {}
	for i=1, cnt do
		temps[i] = read_S_ITEM_TASKPROPS(is)
	end
	data.items = temps  --数据

	return data
end

function send_C_MAP_NODE_ARRIVE(self)  --角色到达结点
	local C_MAP_NODE_ARRIVE = 0x02000006  --角色到达结点
	local sendData = ByteArrayOutputStream()
	sendData:writeInt(0x02000006)
	local param0 = tonumber(self:getExtraValue(0))
	sendData:writeInt(param0)  --关卡结点id
	local param1 = self:getExtraValue(1)
	sendData:writeBool(param1)  --是否到达终点
	sendDataStream(sendData)
end

读xml生成代码例子

标签:

原文地址:http://blog.csdn.net/tutuboke/article/details/43498639

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!