Python之自动化生成解析XML的C++类(基于tinyxml库解析)

来源:互联网 发布:手机淘宝网名怎么修改 编辑:程序博客网 时间:2024/05/29 02:18

## 脚本说明

    该脚本根据用户编写的xml文件,自动生成解析xml串行文本到结构体的类,用于XML通信的模块中,如CMIP(极大的扩展XML通信的灵活性)


## 脚本(xml2Parser.py)

import os,sys,refrom string import TemplategHearFile = "cmip_requestparser"gSrcFile = "cmip_requestparser"gClassName = "CRequestParser"class CObject(object):    #@Consist    def __init__(self):        self._content = ""        self._rootTag = ""        self._subList = []        self._gMap = {}    #@Setter    def setContent(self,content):        self._content = content;    def setRootTage(self,root):        self._rootTag = root    def addSubTag(self,subTag,value):        self._subList.append(subTag)        self._gMap[subTag] = value    #@To    def to_Def_List(self):        ret = ""        for tag in self._subList:            s1 = "\tTiXmlNode * %s_Node;\n" % (tag)            ret += s1        return ret    def to_Init_List(self):        ret = ""        for tag in self._subList:            s1 = "\t%s_Node = NULL;\n" % (tag)            ret += s1        return ret    def to_parse_subTags(self):        nOrder = 1        prefix = ""        ret = ""        for tag in self._subList:            if (nOrder == 1):                prefix = "\t\tif"                nOrder += 1            else:                prefix = "\t\telse if"            s1 = '%s( child->Type() == TiXmlNode::ELEMENT && !strcmp(child->Value(),"%s")){\n' % (prefix,tag)            s1 += '\t\t\t%s_Node = (TiXmlNode *)child->FirstChild();\n' % (tag)            s1 += '\t\t\tif(%s_Node != NULL && %s_Node->Value() != NULL)\n' % (tag,tag)            s1 += '\t\t\t{\n'            xVal = self._gMap[tag].strip()            if re.match("\D",xVal):                s1 += "\t\t\t\tstrcpy(msg->%s,%s_Node->Value());\n" % (tag,tag)            else:                value = "atoi(%s_Node->Value())" % (tag)                s1 += '\t\t\t\tmsg->%s = %s;\n' % (tag ,value)            s1 += '\t\t\t}\n'            s1 += '\t\t}\n'            ret += s1        return ret############################################################################   write string to file.###########################################################################def writeToFile(str,fname):    fp = open(fname,"w+")    fp.write(str)    fp.close()############################################################################   generate the header file.###########################################################################def saveHeadFile(varList):    m_hContent = Template("""/******************************************************************************@fileName    : ${FILE_NAME}.h@description : define for the ${CLASS_NAME} class******************************************************************************/#ifndef ${FILE_NAME_UP}_H#define ${FILE_NAME_UP}_H#include "typedef.h"#include "tinyxml.h"class ${CLASS_NAME}{public:    ${CLASS_NAME}(){}    int parseToMessage(PCHAR pXmlMsg ,Message * msg);private:    TiXmlDocument doc;    iXmlElement *rootElem;${VAR_LIST}};#endif""")    h_str = m_hContent.substitute(FILE_NAME = gHearFile,                                  FILE_NAME_UP = gHearFile.upper(),                                  CLASS_NAME = gClassName,                                  VAR_LIST = varList)    writeToFile(h_str,gHearFile + ".h")    ####################################################################################################[OK]   generate the soruce file.###################################################################################################def saveBodyFile(varInitList,varParseList):    m_bContent = Template("""/********************************************************************************  File name : ${FILE_NAME}.cpp*  Title     : Implementation of the ${CLASS_NAME} class*******************************************************************************/#include "${FILE_NAME}.h"#include <string.h>/*******************************************************************************   @pXmlMsg    :   XML Content.*   @msg        :   Store the Parsed Xml Result.*   @Return     :   0 (OK) ,-1 (Fail)******************************************************************************/INT32 ${CLASS_NAME}::parseToMessage(PCHAR pXmlMsg ,Message * msg){    if(pXmlMsg == NULL || strlen(pXmlMsg) <= 0)        return -1;    if(pXmlMsg == NULL)        return -1;${VAR_INIT_LIST}    doc.Parse(pXmlMsg);    rootElem = doc.RootElement();    if(!rootElem){        return -1;    }    for( const TiXmlNode* child = rootElem->FirstChild();child;child=child->NextSibling() ){${VAR_PARSE_LIST}\t}    return 0;}""")    b_str = m_bContent.substitute(FILE_NAME=gSrcFile,                                  CLASS_NAME=gClassName,                                  VAR_INIT_LIST=varInitList,                                  VAR_PARSE_LIST=varParseList)    writeToFile(b_str,gSrcFile + ".cpp")####################################################################################################[OK]   parse the xml###################################################################################################gObj = CObject()def doParse(xml):    global gObj    cntList =open(xml,'r+').readlines()    print "\n########################################################"    for cnt in cntList:        m = re.match(r'\s*<([^/><?]+)>\s*\n',cnt)        if m:            print "Root:\t%s" % (m.group(1))            gObj.setRootTage(m.group(1))            continue        m = re.match(r'\s*<([^/><]+)>([^><]+)</([^/><]+)>',cnt)        if m:            print "Node:\t%s\t-> %s" % (m.group(1),m.group(2))            gObj.addSubTag(m.group(1),m.group(2))            continue    print "########################################################"####################################################################################################[OK]   The Main Logic###################################################################################################if len(sys.argv) < 2:    print "Usage:\tdev.py test.xml"else:    doParse(sys.argv[1])    vDefList = gObj.to_Def_List()    vInitList = gObj.to_Init_List()    vParseList = gObj.to_parse_subTags()    saveHeadFile(vDefList)    saveBodyFile(vInitList,vParseList)

## 用法说明

xml2parser.py cmip.xml


## xml配置文件内容(cmip.xml)

<resp>

<cmd>2</cmd>

<cmdTarget>3</cmdTarget>

<cmdType>0</cmdType>

<timestamp>12323123123</timestamp>

<parameter>ok</paremeter>

</resp>


## 脚本根据cmip中tag内编写的是数字还是字符串,来断定该C++解析时该tag的值是ini还是string的类型

0 0
原创粉丝点击