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:
charmFrameName[100];//帧名
intmAttrNum;//属性数量
SXMLAttrib*mAttrArray;//属性数组

SXMLFrame*mpSiblFrame;//兄弟结点
SXMLFrame*mpChiFrame;//子结点
SXMLFrame* mpParentFrame;//父结点
public:

SXMLFrame();
~SXMLFrame();

voidRelease_Depath();

SXMLFrame*GetFrame_Depth(char *szFrameName);

intGetChildNum();
SXMLFrame*GetChildFrame(int Index);
SXMLFrame*GetChildFrame(char *szFrameName);
SXMLFrame*GetSiblFrame();
SXMLFrame*GetParentFrame();
SXMLAttrib* GetAttrib(char *szKeyName);


bool ParseAttrString(char *szXMLString);
}
;
class CXMLFile
{
SXMLFramemRoot;
SXMLFrame*mpCurrentFrame;
boolmbDepthClose;//闭合
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;
}
intSXMLFrame::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);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值