#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;
}
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>
生成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
用法,用里面的标示,找到其他的协议把里面的内容复制过来.
也可以用函数返回方式。生成代码这样:
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(), },
fightCap = 10,rankNo = 10,leftAttackCount = 10,leftFreeResetCount = 10,resetExpend = 100,addAttackExpend = 100,
test = read_S_CROSS_ROLE_TOP_THREE(),
score = 10,
gradeRewards = { [1]=true, },
}
return data
end