读取xml生成lua測试代码


#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 << "		";
    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 << "		" ;
                    }
                    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 << "		";
        }
    }
    file << endl;
    file << "	}"  << 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 << "	local 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






原文地址:https://www.cnblogs.com/yxysuanfa/p/6872044.html