读xml生成代码例子

读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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念
xml文件介绍及使用
xml编程(一)-xml语法
XML文件结构和基本语法
第2章 包装类
XML入门的常见问题(二)
Java对象的强、软、弱和虚引用
JS解析XML文件和XML字符串详解
java中枚举的详细使用介绍
了解Xml格式
XML入门的常见问题(四)
深入SQLite多线程的使用总结详解
PlayFramework完整实现一个APP(一)
XML和YAML的使用方法
XML轻松学习总节篇