Linux 下读XML 的类详解及实现代码

 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);    }    

 感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

参与评论