栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > 服务器

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

服务器 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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

在Linux下写程序,常需要读一些配置文件。现有的XML工具很多,可以方便的编辑和生成XML。

但VC中用的XML解析器在Linux下不能用。只好自已写了个。用了一下,还不错。

 #include 
#include 


// ********************************************************************** //
// 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文件。

 




 


 

 

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

}

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/181679.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号