讀xml產生代碼例子,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 dotemps[i] = read_S_ITEM_TASKPROPS(is)enddata.items = temps --資料return dataend
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) --關卡結點idlocal param1 = self:getExtraValue(1)sendData:writeBool(param1) --是否到達終點sendDataStream(sendData)end