#include <iostream> #include <string> #include <fstream> #include "tinyxml2.h" using namespace std; using namespace tinyxml2; std::ofstream file("test.lua",std::ios::ate|std::ios::binary); void read_ElementChild(XMLElement *surface) { string punStr = ","; //标点符号 file << "\t\t"; bool isArray = true; //是否是循环 while (surface) { const XMLAttribute *attr = surface->FirstAttribute(); string strType; while (attr) { if ( strcmp(attr->Name(),"name") == 0 ){ string name = attr->Value(); string preStr = name + " = "; string preStr1 = name + " = { "; string temp; if ( strcmp(strType.c_str(),"String") == 0 ){ isArray = false; temp = "\"呵呵00001\"" + punStr; }else if(strcmp(strType.c_str(),"long")==0){ isArray = false; temp = "100" + punStr; }else if(strcmp(strType.c_str(),"int")==0){ isArray = false; temp = "10" + punStr; }else if(strcmp(strType.c_str(),"short")==0){ isArray = false; temp = "10" + punStr; }else if(strcmp(strType.c_str(),"byte")==0){ isArray = false; temp = "2" + punStr; }else if(strcmp(strType.c_str(),"boolean")==0){ isArray = false; temp = "true" + punStr; }else if(strcmp(strType.c_str(),"float")==0){ isArray = false; temp = "2" + punStr; }else{ if (!isArray){ //如果上次不是循环 这次是循环 换一行 并添加两个tab键空格 file << endl; file << "\t\t" ; } isArray = true; size_t len = strType.size(); string lastStr = strType.substr(len-2,2); if ( strcmp(lastStr.c_str(),"[]" ) == 0 ){ string preStr = strType.substr(0,len-2); if ( strcmp(preStr.c_str(),"String") == 0 ){ temp = "\"呵呵00001\"" + punStr + " }" + punStr; }else if( strcmp(preStr.c_str(),"long")==0){ temp = "100" + punStr + " }" + punStr; }else if( strcmp(preStr.c_str(),"int")==0){ temp = "10" + punStr + " }" + punStr; }else if( strcmp(preStr.c_str(),"short")==0){ temp = "10" + punStr + " }" + punStr; }else if( strcmp(preStr.c_str(),"byte")==0){ temp = "2" + punStr + " }" + punStr; }else if( strcmp(preStr.c_str(),"boolean")==0){ temp = "true" + punStr + " }" + punStr; }else if( strcmp(preStr.c_str(),"float")==0){ temp = "2" + punStr + " }" + punStr; }else { temp = "{ read_" + preStr + " },}" + punStr; } temp = "[1]=" + temp; //数组添加[1] }else{ //处理不是数组 读取别的协议 temp = " read_" + strType + " }" + punStr; } } if (isArray) { file << preStr1 + temp; }else { file << preStr + temp; } }else if ( strcmp(attr->Name(),"type") == 0 ){ strType = attr->Value(); } attr = attr->Next(); //下一个属性 } surface = surface->NextSiblingElement(); //下一个节点 if (isArray && surface != NULL) //处理最后一行如果是数组 不空出一行 { file << endl; file << "\t\t"; } } file << endl; file << "\t}" << endl; } void read_xml(XMLElement *surface) { while (surface) { const XMLAttribute *attr = surface->FirstAttribute(); string name; bool isRead = true; //如果是 C_ 协议就不继续读取了 while (attr) { if ( strcmp(attr->Name(),"name") == 0 ) { name = attr->Value(); string fristStr = name.substr(0,1); string writeStr; if ( strcmp(fristStr.c_str(),"S") == 0 ) { writeStr = "function read_" + name + "()"; }else{ isRead = false; break; } file << writeStr; }else if ( strcmp(attr->Name(),"description") == 0 ) { file << " --" << attr->Value() << endl; } attr = attr->Next(); } if (! isRead) {//如果是 C_ 协议就不继续读取了 surface = surface->NextSiblingElement(); continue; } XMLElement *surface1 = surface->FirstChildElement(); //读取子节点 if (surface1){ file << "\tlocal data = {" << endl; read_ElementChild(surface1); } file << "end" << endl; file << endl; surface = surface->NextSiblingElement(); } } int main(int argc,const char * argv[]) { tinyxml2::XMLDocument myDocument; myDocument.LoadFile("protocol.xml"); XMLElement *rootElement = myDocument.RootElement(); XMLElement *surface = rootElement->FirstChildElement("message"); read_xml(surface); return 0; }
@H_301_0@xml测试数据
<project name="Protocol"> <message id="0x42001003" name="S_CROSS_ARENA_UI" description="跨服争霸场角色信息"> <field type="S_CROSS_ARENA_ROLE_INFO[]" name="roleList" description="角色列表"/> <field type="S_CROSS_ROLE_TOP_THREE_INFO[]" name="topThreeRoles" description="前三名"/> <field type="int" name="fightCap" description="战斗力"/> <field type="int" name="rankNo" description="排名"/> <field type="int" name="leftAttackCount" description="剩余战斗攻击次数"/> <field type="int" name="leftFreeResetCount" description="剩余免费重置次数"/> <field type="long" name="resetExpend" description="增加战斗次数消耗钻石数"/> <field type="long" name="addAttackExpend" description="增加战斗次数消耗钻石数"/> <field type="S_CROSS_ROLE_TOP_THREE" name="test" description="消耗"/> <field type="int" name="score" description="积分"/> <field type="boolean[]" name="gradeRewards" description="三个档次的奖励是否可领取"/> </message> </project>
@H_301_0@生成lua
function read_S_CROSS_ARENA_UI(self) --跨服争霸场角色信息 local data = { roleList = { [1]={ read_S_CROSS_ARENA_ROLE_INFO },},topThreeRoles = { [1]={ read_S_CROSS_ROLE_TOP_THREE_INFO },fightCap = 10,rankNo = 10,leftAttackCount = 10,leftFreeResetCount = 10,resetExpend = 100,addAttackExpend = 100,test = { read_S_CROSS_ROLE_TOP_THREE },score = 10,gradeRewards = { [1]=true,} end
用法,用里面的标示,找到其他的协议把里面的内容复制过来. @H_301_0@
@H_301_0@也可以用函数返回方式。生成代码这样:
function read_S_CROSS_ARENA_UI() --跨服争霸场角色信息 local data = { roleList = { [1]= read_S_CROSS_ARENA_ROLE_INFO(),topThreeRoles = { [1]= read_S_CROSS_ROLE_TOP_THREE_INFO(),test = read_S_CROSS_ROLE_TOP_THREE(),} return data end