Linux 下读XML 的类详解及实现代码
程序员文章站
2023-03-25 11:46:24
linux 下读xml 的类详解及实现代码
在linux下写程序,常需要读一些配置文件。现有的xml工具很多,可以方便的编辑和生成xml。
但vc中用的xm...
linux 下读xml 的类详解及实现代码
在linux下写程序,常需要读一些配置文件。现有的xml工具很多,可以方便的编辑和生成xml。
但vc中用的xml解析器在linux下不能用。只好自已写了个。用了一下,还不错。
#include <stdio.h> #include <stdlib.h> // ********************************************************************** // // xml解析类(honghaier写于2008-11-19) // ********************************************************************** // struct sxmlattrib { char mkeyname[100]; //键名 char mvalue[100]; //键值 } ; struct sxmlframe { public: char mframename[100]; //帧名 int mattrnum; //属性数量 sxmlattrib* mattrarray; //属性数组 sxmlframe* mpsiblframe; //兄弟结点 sxmlframe* mpchiframe; //子结点 sxmlframe* mpparentframe; //父结点 public: sxmlframe(); ~sxmlframe(); void release_depath(); sxmlframe* getframe_depth(char *szframename); int getchildnum(); sxmlframe* getchildframe(int index); sxmlframe* getchildframe(char *szframename); sxmlframe* getsiblframe(); sxmlframe* getparentframe(); sxmlattrib* getattrib(char *szkeyname); bool parseattrstring(char *szxmlstring); } ; class cxmlfile { sxmlframe mroot; sxmlframe* mpcurrentframe; bool mbdepthclose; //闭合 private: bool parseframestring(char *szxmlstring); public: int pfile; cxmlfile(); ~cxmlfile(); void close(); void release(); bool open( const char * pfilename); sxmlframe* getroot(); sxmlframe* getframe_depth(char *szframename); } ; //==================================================== sxmlframe::sxmlframe() { memset(mframename,0,sizeof(mframename)); mattrnum = 0; mattrarray = null; mpsiblframe = null; mpchiframe = null; mpparentframe = null; } sxmlframe::~sxmlframe() { release_depath(); } void sxmlframe::release_depath() { if(mattrnum > 0) { if(mattrarray) { delete[] mattrarray; mattrarray = null; } mattrnum = 0; } if(mpchiframe) { mpchiframe->release_depath(); delete mpchiframe; mpchiframe = null; } if(mpsiblframe) { mpsiblframe->release_depath(); delete mpsiblframe; mpsiblframe = null; } } sxmlframe* sxmlframe::getframe_depth(char *szframename) { if(strcmp(mframename,szframename)==0) { return this; } if(mpchiframe) { sxmlframe* tresframe = mpchiframe->getframe_depth(szframename); if(tresframe)return tresframe; } if(mpsiblframe) { sxmlframe* tresframe = mpsiblframe->getframe_depth(szframename); if(tresframe)return tresframe; } return null; } int sxmlframe::getchildnum() { int count = 0; for(sxmlframe *temp = mpchiframe ; temp != null ;temp = temp->mpsiblframe) { count++; } return count; } sxmlframe* sxmlframe::getchildframe(int index) { int count = 0; for(sxmlframe *temp = mpchiframe ; temp != null ;temp = temp->mpsiblframe) { if(count == index)return temp; count++; } return null; } sxmlframe* sxmlframe::getchildframe(char *szframename) { for(sxmlframe *temp = mpchiframe ; temp != null ;temp = temp->mpsiblframe) { if(strcmp(temp->mframename,szframename)==0) { return temp; } } return null; } sxmlframe* sxmlframe::getsiblframe() { return mpsiblframe; } sxmlframe* sxmlframe::getparentframe() { return mpparentframe; } sxmlattrib* sxmlframe::getattrib(char *szkeyname) { for(int i = 0 ; i < mattrnum ; i++) { if(strcmp(mattrarray[i].mkeyname,szkeyname)==0) { return &mattrarray[i]; } } return null; } bool sxmlframe::parseattrstring(char *szxmlstring) { sxmlattrib attribarray[100]; int len = strlen(szxmlstring); mattrnum = 0; int strpos = 0; bool haveframename = false; for(int i = 0 ;i < len ; i++) { if(i==(len-1)) { if(false == haveframename) { memcpy(mframename,szxmlstring,len); mframename[len]='/0'; haveframename = true; } else { if(( len - strpos-1 )== 0) { memset(attribarray[mattrnum].mvalue,0,sizeof(attribarray[mattrnum].mvalue)); } else { memcpy(attribarray[mattrnum].mvalue,szxmlstring+strpos,len-strpos-1); attribarray[mattrnum].mvalue[len-strpos-1]='/0'; } mattrnum++; strpos = 0; } break; } if(szxmlstring[i] == ' '&&szxmlstring[i-1] == ' ') { strpos = i+1; continue; } if(szxmlstring[i] == ' ') { if(false == haveframename) { memcpy(mframename,szxmlstring,i); mframename[i]='/0'; haveframename = true; strpos = i+1; continue; } else { if(( i - strpos-1 )== 0) { memset(attribarray[mattrnum].mvalue,0,sizeof(attribarray[mattrnum].mvalue)); } else { memcpy(attribarray[mattrnum].mvalue,szxmlstring+strpos,i-strpos-1); attribarray[mattrnum].mvalue[i-strpos-1]='/0'; } mattrnum++; strpos = i+1; continue; } } if(szxmlstring[i] == '=') { memcpy(attribarray[mattrnum].mkeyname,szxmlstring+strpos,i-strpos); attribarray[mattrnum].mkeyname[i-strpos]='/0'; i++;//跳过一个""" strpos = i+1; continue; } } mattrarray = new sxmlattrib[mattrnum]; if(!mattrarray)return false; memcpy(mattrarray,attribarray,mattrnum*sizeof(sxmlattrib)); return true; } cxmlfile::cxmlfile() { pfile = 0; mpcurrentframe = null; mbdepthclose = false; } cxmlfile::~cxmlfile() { close(); } void cxmlfile::close() { if( pfile>0) { int error = close( pfile); if( error!=0) { perror("close file failed"); }else { pfile=-1; } release(); } } void cxmlfile::release() { mroot.release_depath(); } bool cxmlfile::open( const char * pfilename) { pfile =0; pfile = open( pfilename,o_rdonly); if( pfile==-1) { perror(pfilename); return false; } int num = 0; char buffer; bool breadxmlstring = false; int xmlstringnum = 0; char xmlstring[1024]; while(num = read(pfile,&buffer,1)>0) { if(buffer =='<') { breadxmlstring = true; xmlstringnum = 0; continue; } if(buffer == '>') { xmlstring[xmlstringnum]='/0'; if( false == parseframestring(xmlstring)) { printf("read xml error: %s /n",xmlstring); return false; } breadxmlstring = false; continue; } if(true == breadxmlstring) { xmlstring[xmlstringnum++] = buffer; } } mpcurrentframe = null; mbdepthclose = true; return true; } sxmlframe* cxmlfile::getroot() { return &mroot; } sxmlframe* cxmlfile::getframe_depth(char *szframename) { return mroot.getframe_depth(szframename); } bool cxmlfile::parseframestring(char *szxmlstring) { if(szxmlstring[0] == '?')return true; if(szxmlstring[0] == '!')return true; if(szxmlstring[0] == '/') { //如果是结束 mpcurrentframe = mpcurrentframe->getparentframe(); mbdepthclose = true; } else { mbdepthclose = false; if( null == mpcurrentframe) { mpcurrentframe = &mroot; } sxmlframe* tnewframe = new sxmlframe; tnewframe->parseattrstring(szxmlstring); if(false == mbdepthclose) { tnewframe->mpparentframe = mpcurrentframe; if( null == mpcurrentframe->mpchiframe) { mpcurrentframe->mpchiframe = tnewframe; } else { for(sxmlframe *temp = mpcurrentframe->mpchiframe ; temp != null ;temp = temp->mpsiblframe) { if( null == temp->mpsiblframe) { temp->mpsiblframe = tnewframe; break; } } } mpcurrentframe = tnewframe; } else { tnewframe->mpparentframe = mpcurrentframe->getparentframe(); mpcurrentframe->mpsiblframe = tnewframe; mpcurrentframe = tnewframe; } } return true; }
用xml工具做了一个简单的xml文件。
<?xml version="1.0" encoding="utf-8"?> <!-- edited with xml explorer v2.0 by mergesoft (www.mergesoft.com)--> <root> <honghaier name="红孩儿" age="26"></honghaier> </root>
在c++代码中
可以这样使用
cxmlfile xmlfile; xmlfile.open("1.xml"); sxmlframe* mrootframe = cxmlfile::getroot(); int childnum = mrootframe ->getchildnum(); for(int i = 0 ; i < childnum ; i++) { sxmlframe* tchileframe = mrootframe ->getchildframe (i); sxmlattrib* tattrib = tchileframe->getattrib("age"); print("%s : %s= %s /n",mchileframe ->mframename,tattrib->mkeyname,tattrib->mvalue); }
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
下一篇: CPU超频详细设置教程