首页 > 系统相关 >Linux 下读XML 的类

Linux 下读XML 的类

时间:2023-04-03 11:38:36浏览次数:39  
标签:XML return temp SXMLFrame char mAttrNum Linux 下读 NULL


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


 

标签:XML,return,temp,SXMLFrame,char,mAttrNum,Linux,下读,NULL
From: https://blog.51cto.com/u_15941225/6165857

相关文章

  • Linux数据盘挂载
    在我们使用云服务器时,一般会分两个磁盘:系统盘与数据盘,一般情况数据盘是需要手动去挂载的。一、查看系统磁盘信息1.1 查看磁盘信息列出所有可用块设备的信息,而且还能显示他们之间的依赖关系,但是它不会列出RAM盘的信息lsblk1.2 硬盘实体使用情况,也可对硬盘分区fdisk-l......
  • XmlTextReader正由另一进程使用,因此该进程无法访问此文件
    此处调用报错:publicvoidsetMaxValueByXml(stringJym,stringvalueMax){XmlDocumentxmlDoc=newXmlDocument();xmlDoc.Load(Server.MapPath("XMLData.xml"));XmlNodeListnodeList=xmlDoc.SelectSingleNode("body")......
  • 制作Linux程序监控脚本
    程序监控脚本guard_cmms.sh#!/bin/bash#需要守护的进程数组,将需要守护的进程填入数组中,如PRO_NAMES=(./bin/pro1./pro2)表示要守护pro1、pro2进程PRO_NAMES=("maincmms""haikangaccessdevice""dahuaaccessdevice")#不保存控制台输出日志OUTPUT="/dev/null"#守......
  • 汇总Linux、Git命令、工具
    基本命令uname-m显示机器的处理器架构uname-r显示正在使用的内核版本dmidecode-q显示硬件系统部件hdparm-tT/dev/sda在磁盘上执行测试性读取操作系统信息arch显示机器的处理器架构uname-m显示机器的处理器架构hdparm-i/dev/hda罗列一个磁盘的架构特性cat......
  • linux基本功系列之yum命令
    1.yum命令介绍1.1yum的介绍yum命令来自于英文词组”YellowdogUpdater,Modified“的缩写,其功能是用于在Linux系统中基于RPM技术进行软件包的管理工作。YUM是C/S架构的在线软件安装命令,是RPM1的前端工具,依赖于RPM存在的。能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖......
  • Linux|--sh脚本|--文件执行报错::Error response from daemon: invalid reference for
    前言由于Linux中的docker镜像和容器需要批量处理,所以搞一个脚本,直接一下处理了,1.我在Windows10的本机电脑上新建了一个"test.sh"文件2.将"test.sh"文件上传到Linux环境中3.在Linux中执行"shtest.sh"4.报错了...第一次报错信息[root@VM-4-3-centostest_api]#shdock......
  • NETCONF、XML、YANG之间的关系
    目录NETCONF、XML、YANG之间的关系参考引用理解XMLYANG操作层数据库基本能力标准能力集扩展能力集总结NETCONF、XML、YANG之间的关系参考引用https://support.huawei.com/enterprise/zh/doc/EDOC1100202502/9698cb86https://support.huawei.com/enterprise/zh/doc/EDOC1100278535/d......
  • linux内核数据结构 --- list_head
    以structkobject为例,讲解如何使用链表structlist_headstructkobject{constchar*name;structlist_headentry;structkobject*parent;...};structlist_head类型变量作为structkobject的成员(从面向对象的角度,也可以看成str......
  • Linux系统下添加防火墙规则(添加白名单)
     Linux系统下添加防火墙规则(添加白名单)防火墙的作用:  可以通过设置ip白名单/黑名单的方式限制外部ip的访问或者限制访问内部某个端口;添加防火墙过滤规则步骤如下;1、查看现有防火墙过滤规则:  iptables-nvL--line-number2、添加防火墙过滤规则(设置白名单):    1......
  • Linux数据分析之九个给力的命令行工具
    导读要对数据进行分析,大家会从哪里入手?对于大多数熟悉了图形工作环境的朋友来说,电子表格工具无疑是第一选项。但命令行工具同样能够更快更高效地解决问题——且只须稍微学习即可上手。要对数据进行分析,大家会从哪里入手?对于大多数熟悉了图形工作环境的朋友来说,电子表......