Linux 下讀XML 的類(lèi)詳解及實(shí)現(xiàn)代碼
Linux 下讀XML 的類(lèi)詳解及實(shí)現(xiàn)代碼
在Linux下寫(xiě)程序,常需要讀一些配置文件。現(xiàn)有的XML工具很多,可以方便的編輯和生成XML。
但VC中用的XML解析器在Linux下不能用。只好自已寫(xiě)了個(gè)。用了一下,還不錯(cuò)。
#include <stdio.h>
#include <stdlib.h>
// ********************************************************************** //
// XML解析類(lèi)(honghaier寫(xiě)于2008-11-19)
// ********************************************************************** //
struct SXMLAttrib
{
char mKeyName[100]; //鍵名
char mValue[100]; //鍵值
}
;
struct SXMLFrame
{
public:
char mFrameName[100]; //幀名
int mAttrNum; //屬性數(shù)量
SXMLAttrib* mAttrArray; //屬性數(shù)組
SXMLFrame* mpSiblFrame; //兄弟結(jié)點(diǎn)
SXMLFrame* mpChiFrame; //子結(jié)點(diǎn)
SXMLFrame* mpParentFrame; //父結(jié)點(diǎn)
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++;//跳過(guò)一個(gè)"""
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] == '/')
{
//如果是結(jié)束
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工具做了一個(gè)簡(jiǎn)單的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);
}
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
阿里云linux服務(wù)器安全設(shè)置(防火墻策略等)
這篇文章主要介紹了阿里云linux服務(wù)器安全設(shè)置,主要是針對(duì)防火墻策略等一些補(bǔ)充2016-10-10
ubuntu系統(tǒng)修改時(shí)區(qū)和時(shí)間的方法
今天小編就為大家分享一篇關(guān)于ubuntu系統(tǒng)修改時(shí)區(qū)和時(shí)間的方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03
在Debian系的Linux中編譯并安裝ixgbe驅(qū)動(dòng)的教程
這篇文章主要介紹了在Linux中編譯并安裝ixgbe驅(qū)動(dòng)的教程,采用bash shell、適用于Debian、Ubuntu等各種基于Debian的Linux系統(tǒng),需要的朋友可以參考下2015-03-03
linux/OSX中“DD”命令制作ISO鏡像操作系統(tǒng)安裝U盤(pán)的方法
這篇文章主要介紹了linux/OSX中“DD”命令制作ISO鏡像操作系統(tǒng)安裝U盤(pán)的方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-09-09
Apache和Tomcat有什么區(qū)別_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
Apache 和 Tomcat 都是web網(wǎng)絡(luò)服務(wù)器,兩者既有聯(lián)系又有區(qū)別。下面通過(guò)本文給大家介紹Apache和Tomcat的區(qū)別,感興趣的朋友一起看看吧2017-08-08
linux下查看已經(jīng)安裝的jdk 并卸載jdk的方法(推薦)
下面小編就為大家?guī)?lái)一篇linux下查看已經(jīng)安裝的jdk 并卸載jdk的方法(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-11-11
解決Linux中nohup.out日志過(guò)大問(wèn)題
這篇文章主要介紹了解決Linux中nohup.out日志過(guò)大問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05

