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

发布时间 - 2026-01-11 00:03:31    点击率:

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

}

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


# Linux  # 读XML  # 的类  # 的类实现代码  # LINUX 查找tomcat日志关键词命令  # Linux 下安装 memcached 及 memcacheq的方法  # Linux服务器下PHPMailer发送邮件失败的问题解决  # Linux在shell中自动生成1到100的数组方法(两种方法)  # Linux 单个tomcat多实例部署shell脚本详解  # Linux 中的nc命令小结  # 详解阿里云LINUX服务器配置HTTPS(NGINX)  # Linux UDP socket 设置为的非阻塞模式与阻塞模式区别  # 用了  # 希望能  # 写了  # 还不错  # 不能用  # 谢谢大家  # 跳过  # 配置文件  # 键值  # 写于  # 键名  # GetChildNum  # szFrameName  # GetFrame_Depth  # GetSiblFrame  # Index  # GetChildFrame  # mpParentFrame  # mpChiFrame  # mpSiblFrame 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 高防服务器租用指南:配置选择与快速部署攻略  车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?  微信小程序制作网站有哪些,微信小程序需要做网站吗?  如何在沈阳梯子盘古建站优化SEO排名与功能模块?  如何在 Go 中优雅地映射具有动态字段的 JSON 对象到结构体  如何用PHP快速搭建CMS系统?  如何注册花生壳免费域名并搭建个人网站?  详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)  Laravel怎么创建自己的包(Package)_Laravel扩展包开发入门到发布  html5怎么画眼睛_HT5用Canvas或SVG画眼球瞳孔加JS控制动态【绘制】  Laravel Sail是什么_基于Docker的Laravel本地开发环境Sail入门  如何自定义safari浏览器工具栏?个性化设置safari浏览器界面教程【技巧】  如何用AI一键生成爆款短视频文案?小红书AI文案写作指令【教程】  HTML透明颜色代码在Angular里怎么设置_Angular透明颜色使用指南【详解】  悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音  javascript日期怎么处理_如何格式化输出  北京专业网站制作设计师招聘,北京白云观官方网站?  学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?  香港服务器建站指南:免备案优势与SEO优化技巧全解析  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?  制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?  linux写shell需要注意的问题(必看)  三星网站视频制作教程下载,三星w23网页如何全屏?  北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?  如何快速打造个性化非模板自助建站?  香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南  Java类加载基本过程详细介绍  JS中对数组元素进行增删改移的方法总结  iOS验证手机号的正则表达式  Java遍历集合的三种方式  猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?  Windows10如何更改计算机工作组_Win10系统属性修改Workgroup  Laravel如何使用Seeder填充数据_Laravel模型工厂Factory批量生成测试数据【方法】  高性能网站服务器部署指南:稳定运行与安全配置优化方案  *服务器网站为何频现安全漏洞?  Windows Hello人脸识别突然无法使用  如何在建站之星绑定自定义域名?  如何快速搭建FTP站点实现文件共享?  如何在IIS中配置站点IP、端口及主机头?  如何基于PHP生成高效IDC网络公司建站源码?  BootStrap整体框架之基础布局组件  Laravel项目怎么部署到Linux_Laravel Nginx配置详解  Laravel安装步骤详细教程_Laravel环境搭建指南  如何在服务器上三步完成建站并提升流量?  Linux系统命令中screen命令详解  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  Android 常见的图片加载框架详细介绍  谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复  如何在阿里云部署织梦网站?