expat下载地址:http://sourceforge.net/projects/expat/
互联网发得展很快,都是源自于使用了超文本的表达方式。比如你查看一篇文章,看到不懂的关键字,就可以通过链接去查看它的内容,看完之后再回来接着看原来的东西,这样比较适合学习的方式。使用HTML标记的文本,是结构化储存的,这样的表达方式才可以实现超级连接。由于HTML具有超强的表达能力,也就在互联网上生存下来,那么人们就会想到能不能使用这种方式来保存所有需要保存的内容呢?慢慢地就开发XML标记语言,用来保存任意想保存的内容。由于XML具有HTML同样的功能,并且不限定标记,这样就可以表达所有的东西了。并且XML是基于树形结构的,想表达的信息就可以采用归类树的方式来组织内容了,这样能产生灵活可变的内容管理方式。比如在第二人生里采用参数配置文件,也是选择XML来保存的,并且使用expat的XML解析器来实现这方面的内容。接着下来,我们就来了解一下expat是什么东东,又是怎么样调用它来解析XML文件的。
expat是使用C编写的XML解释器,采用流的方式来解析XML文件,并且基于事件通知型来调用分析到的数据,并不需要把所有XML文件全部加载到内存里,这样可以分析非常大的XML文件。由于expat库是由XML的主要负责人James Clark来实现的,因此它是符合W3C的XML标准的。
使用expat库是非常简单的,只需要了解四个函数,就可以达到80%的功能了,看来设计这个库还是比较好的。那么需要了解那四个函数呢?这四个函数如下:
XML_ParserCreate 创建一个XML分析器。
XML_SetElementHandler 设置处理标记开始和结束的处理函数。
XML_SetCharacterDataHandler 设置处理不同字符集的数据。
XML_Parse 分析给出的缓冲区XML数据。
通过调用上面四个函数就可以实现expat调用了,使用它就是这么方便简单的。
expat是使用C编写的XML解释器,采用流的方式来解析XML文件,并且基于事件通知型来调用分析到的数据,并不需要把所有XML文件全部加载到内存里,这样可以分析非常大的XML文件。由于expat库是由XML的主要负责人James Clark来实现的,因此它是符合W3C的XML标准的。
使用expat库是非常简单的,只需要了解四个函数,就可以达到80%的功能了,看来设计这个库还是比较好的。那么需要了解那四个函数呢?这四个函数如下:
XML_ParserCreate 创建一个XML分析器。
XML_SetElementHandler 设置处理标记开始和结束的处理函数。
XML_SetCharacterDataHandler 设置处理不同字符集的数据。
XML_Parse 分析给出的缓冲区XML数据。
通过调用上面四个函数就可以实现expat调用了,使用它就是这么方便简单的。
CODE
- //无双loveunix.net转载请保留出处
- #include<cstdlib>
- #include<fstream>
- #include<iostream>
- #include<cstring>
- #include<string>
- #include<expat.h>
- usingnamespacestd;
- #defineXML_MMSC_LISTEN_PORT"MMSC_LISTEN_PORT"
- #defineXML_CLIENT_LISTEN_PORT"CLIENT_LISTEN_PORT"
- #defineXML_MMSC_FROMADDR"MMSC_FROMADDR"
- #defineXML_MMSC_IPADDR"MMSC_IPADDR"
- #defineXML_MMSC_ROOT"MMSC_ROOT"
- #defineXML_MMSC_PORT"MMSC_PORT"
- #defineXML_MMSC_LOGIN_NAME"MMSC_LOGIN_NAME"
- #defineXML_MMSC_LOGIN_PWD"MMSC_LOGIN_PWD"
- #defineXML_MMSC_VASP_ID"MMSC_VASP_ID"
- #defineXML_MMSC_VAS_ID"MMSC_VAS_ID"
- #defineXML_MMS_SUBMIT_REPEATTIME"MMS_SUBMIT_REPEATTIME"
- enumCONF_TYPE{EM_UNUSE=0,
- EM_LSN_MMSC_PORT,EM_LSN_CLN_PORT,EM_SENDREPEAT,
- EM_MMSC_IP,EM_MMSC_PORT,EM_MMSC_ROOT,
- EM_FROM,EM_VASPID,EM_VASID,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> EM_AUTHNAME,EM_AUTHPWD
- };
- structXML_MMSCConfInfo{
- intDepth;
- intElement;
- intMMSC_LISTEN_PORT;
- intCLIENT_LISTEN_PORT;
- charMMSC_FROMADDR[50];
- charMMSC_IPADDR[16];
- charMMSC_ROOT[255];
- intMMSC_PORT;
- charMMSC_LOGIN_NAME[255];
- charMMSC_LOGIN_PWD[255];
- charMMSC_VASP_ID[255];
- charMMSC_VAS_ID[255];
- intMMS_SUBMIT_REPEATTIME;
- };
- staticintGetID(constchar*name){
- if(!stricmp(name,XML_MMSC_LISTEN_PORT))returnEM_LSN_MMSC_PORT;
- returnEM_LSN_CLN_PORT;
- returnEM_FROM;
- returnEM_MMSC_IP;
- returnEM_MMSC_ROOT;
- returnEM_MMSC_PORT;
- returnEM_AUTHNAME;
- returnEM_AUTHPWD;
- returnEM_VASPID;
- returnEM_VASID;
- returnEM_SENDREPEAT;
- returnEM_UNUSE;
- }
- intSetElementValue(XML_MMSCConfInfo&Conf,char*Value)
- {
- boolHasQoute=false;
- char*pstart=strchr(Value,'"');
- char*pend;
- if(!pstart){
- pstart=Value;
- pend=pstart;
- }
- else{
- pend=strchr(++pstart,'"');
- if(!pend)return-1;
- HasQoute=true;
- intlen=pend-pstart;
- switch(Conf.Element){
- caseEM_LSN_MMSC_PORT:
- Conf.MMSC_LISTEN_PORT=atoi(pstart);
- break;
- caseEM_LSN_CLN_PORT:
- Conf.CLIENT_LISTEN_PORT=atoi(pstart);
- break;
- caseEM_SENDREPEAT:
- Conf.MMS_SUBMIT_REPEATTIME=atoi(pstart);
- caseEM_MMSC_IP:
- if(!HasQoute)return-1;
- strncpy(Conf.MMSC_IPADDR,pstart,len>sizeof(Conf.MMSC_IPADDR)
- ?sizeof(Conf.MMSC_IPADDR):len);
- caseEM_MMSC_PORT:
- Conf.MMSC_PORT=atoi(pstart);
- caseEM_MMSC_ROOT:
- strncpy(Conf.MMSC_ROOT,153); background-color:inherit; font-weight:bold">sizeof(Conf.MMSC_ROOT)?
- sizeof(Conf.MMSC_ROOT):len);
- caseEM_FROM:
- strncpy(Conf.MMSC_FROMADDR,153); background-color:inherit; font-weight:bold">sizeof(Conf.MMSC_FROMADDR)?
- sizeof(Conf.MMSC_FROMADDR):len);
- caseEM_VASPID:
- strncpy(Conf.MMSC_VASP_ID,153); background-color:inherit; font-weight:bold">sizeof(Conf.MMSC_VASP_ID)?
- sizeof(Conf.MMSC_VASP_ID):len);
- caseEM_VASID:
- strncpy(Conf.MMSC_VAS_ID,153); background-color:inherit; font-weight:bold">sizeof(Conf.MMSC_VAS_ID)?
- sizeof(Conf.MMSC_VAS_ID):len);
- caseEM_AUTHNAME:
- strncpy(Conf.MMSC_LOGIN_NAME,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> len>sizeof(Conf.MMSC_LOGIN_NAME)?
- sizeof(Conf.MMSC_LOGIN_NAME):len);
- caseEM_AUTHPWD:
- strncpy(Conf.MMSC_LOGIN_PWD,153); background-color:inherit; font-weight:bold">sizeof(Conf.MMSC_LOGIN_PWD)?
- sizeof(Conf.MMSC_LOGIN_PWD):len);
- default:
- return0;
- staticvoidXMLCALL
- xmlstart(void*data,87); background-color:inherit; font-weight:bold">char*el,87); background-color:inherit; font-weight:bold">char**attr)
- XML_MMSCConfInfo*pmmscinf=(XML_MMSCConfInfo*)data;
- for(inti=0;attr[i];i++){
- pmmscinf->Element=GetID(attr[i]);
- SetElementValue(*pmmscinf,attr[i+1]);
- pmmscinf->Element=GetID(el);
- pmmscinf->Depth++;
- xmlend(char*el)
- ((XML_MMSCConfInfo*)data)->Element=EM_UNUSE;
- ((XML_MMSCConfInfo*)data)->Depth--;
- voidXMLCALL
- parsedata(void*userData,153); background-color:inherit; font-weight:bold">constXML_Char*s,intlen)
- {
- stringstr;
- str.assign(s,len);
- SetElementValue(*(XML_MMSCConfInfo*)userData,str.c_str());
- /**
- *@brief解析MMSC配置文件
- *
- *@return-1失败0成功
- **/
- intParseMMSCConf(XML_MMSCConfInfo&Conf,87); background-color:inherit; font-weight:bold">char*FileName)
- memset(&Conf,sizeof(XML_MMSCConfInfo));
- ifstreamifs(FileName,ios::in|ios::binary);
- if(!ifs)
- char*buf;
- intlen;
- ifs.seekg(0,ios::end);
- len=ifs.tellg();
- buf=newchar[len];
- if(buf)
- ifs.read(buf,len);
- ifs.close();
- if(!buf)
- intdone=0;
- interr=0;
- XML_Parserparser=XML_ParserCreate(NULL);
- if(!parser){
- cerr<<"Couldn'tallocatememoryforparser"<<endl;
- XML_SetElementHandler(parser,xmlstart,xmlend);
- XML_SetUserData(parser,&Conf);
- XML_SetCharacterDataHandler(parser,parsedata);
- if(XML_Parse(parser,buf,len,done)
- ==XML_STATUS_ERROR){
- cerr<<XML_ErrorString(XML_GetErrorCode(parser))<<"atline"
- <<XML_GetCurrentLineNumber(parser)<<endl;
- err=1;
- ifs.close();
- XML_ParserFree(parser);
- returnerr;
- staticSerialize(constXML_MMSCConfInfo&Conf)
- printf("XML_MMSCConfInfois:/n"
- "/tDepth:%d/tElement:%d/n"
- "/tMSC_LISTEN_PORT:%d/tCLIENT_LISTEN_PORT:%d/n"
- "/tMMSC_FROMADDR:[%s]MMSC_IPADDR:[%s]tMMSC_PORT:%d/n"
- "/tMMSC_ROOT:[%s]/tMSC_LOGIN_NAME:[%s]/tMMSC_LOGIN_PWD:[%s]/n"
- "/tMMSC_VASP_ID:[%s]/tMMSC_VAS_ID:[%s]/tMMS_SUBMIT_REPEATTIME:%d/n",108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> Conf.Depth,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> Conf.Element,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> Conf.MMSC_LISTEN_PORT,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> Conf.CLIENT_LISTEN_PORT,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> Conf.MMSC_FROMADDR,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> Conf.MMSC_IPADDR,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> Conf.MMSC_PORT,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> Conf.MMSC_ROOT,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> Conf.MMSC_LOGIN_NAME,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> Conf.MMSC_LOGIN_PWD,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> Conf.MMSC_VASP_ID,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> Conf.MMSC_VAS_ID,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> Conf.MMS_SUBMIT_REPEATTIME);
- voidmain()
- test();
- XML_MMSCConfInfoConf;
- ParseMMSCConf(Conf,"conf.xml");
- Serialize(Conf);
- }
xml文件内容如下
CODE
- <?xmlversion="1.0"encoding="gb2312"?>
- <mmscconf>
- MMSC_LISTEN_PORT>8801</>
- CLIENT_LISTEN_PORT>8902
- MMSC_FROMADDR>"+8613821113111/TYPE=PLMN"MMSC_IPADDR>"172.16.65.187"MMSC_ROOT>"/"MMSC_PORT>9000MMSC_LOGIN_NAME>"nan"MMSC_LOGIN_PWD>"whuang"MMSC_VASP_ID>"999999"MMSC_VAS_ID>"9999"MMS_SUBMIT_REPEATTIME>3>
使用expat时不会帮助检查xml语法 所以你必须保证要分析的xml文件是对的
中文版
[cpp]
copy
- 中文xml文件的处理或是其它非标准编码xml文件的处理
- expat内建只支持utf-8ucs2us-asciiiso8859-1编码
- 其它的编码必须设置XML_SetUnknownEncodingHandler
- CODE
- /*
- *=====================================================================================
- *
- *Filename:getinfo.cpp
- *Description:使用expat开发xml例子程序,包括对中文xml的支持
- *Version:1.0
- *Created:2004-03-1715:17:34中国标准时间
- *Revision:none
- *Author:无双[lizl@yztelecom.com]
- *Company:www.loveunix.net
- *
- *=====================================================================================
- */
- #include<cstdlib>
- #include<fstream>
- #include<iostream>
- #include<cstring>
- #include<string>
- #include<windows.h>
- #include<expat.h>
- namespacestd;
- #defineXML_MMSC_LISTEN_PORT"MMSC_LISTEN_PORT"
- #defineXML_CLIENT_LISTEN_PORT"CLIENT_LISTEN_PORT"
- #defineXML_MMSC_FROMADDR"MMSC_FROMADDR"
- #defineXML_MMSC_IPADDR"MMSC_IPADDR"
- #defineXML_MMSC_ROOT"MMSC_ROOT"
- #defineXML_MMSC_PORT"MMSC_PORT"
- #defineXML_MMSC_LOGIN_NAME"MMSC_LOGIN_NAME"
- #defineXML_MMSC_LOGIN_PWD"MMSC_LOGIN_PWD"
- #defineXML_MMSC_VASP_ID"MMSC_VASP_ID"
- #defineXML_MMSC_VAS_ID"MMSC_VAS_ID"
- #defineXML_MMS_SUBMIT_REPEATTIME"MMS_SUBMIT_REPEATTIME"
- EM_LSN_MMSC_PORT,
- EM_MMSC_IP,
- EM_FROM,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> EM_AUTHNAME,EM_AUTHPWD
- };
- structXML_MMSCConfInfo{
- intDepth;
- intElement;
- intMMSC_LISTEN_PORT;
- intCLIENT_LISTEN_PORT;
- charMMSC_FROMADDR[50];
- charMMSC_IPADDR[16];
- charMMSC_ROOT[255];
- intMMSC_PORT;
- charMMSC_LOGIN_NAME[255];
- charMMSC_LOGIN_PWD[255];
- charMMSC_VASP_ID[255];
- charMMSC_VAS_ID[255];
- intMMS_SUBMIT_REPEATTIME;
- };
- intConvertFromUTF8(char*strout,87); background-color:inherit; font-weight:bold">intstroutlen,87); background-color:inherit; font-weight:bold">char*Text,87); background-color:inherit; font-weight:bold">intTextLen)
- {
- //转换utf-8编码到gb2312,linux下使用iconv函数可以直接转换,
- //在win下需要先转换到ucs2再从ucs2转换到utf-8
- WCHARWCharBuf[_MAX_PATH];
- LPWSTRpTransBuf=WCharBuf;
- intTransBufLen=_MAX_PATH;
- if(TextLen>=_MAX_PATH){
- TransBufLen=TextLen;
- pTransBuf=WCHAR[TransBufLen];
- if(!pTransBuf)
- return0;
- }
- intlength=MultiByteToWideChar(CP_UTF8,Text,TextLen,
- pTransBuf,TransBufLen);
- length=WideCharToMultiByte(CP_ACP,pTransBuf,length,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> strout,stroutlen,NULL,NULL);
- if(pTransBuf!=WCharBuf)
- delete[]pTransBuf;
- returnlength;
- }
- char*name){
- returnEM_LSN_MMSC_PORT;
- returnEM_LSN_CLN_PORT;
- returnEM_FROM;
- returnEM_MMSC_IP;
- returnEM_MMSC_ROOT;
- returnEM_MMSC_PORT;
- returnEM_AUTHNAME;
- returnEM_AUTHPWD;
- returnEM_VASPID;
- returnEM_VASID;
- returnEM_SENDREPEAT;
- returnEM_UNUSE;
- char*Value)
- {
- false;
- '"');
- char*pend;
- if(!pstart){
- pstart=Value;
- pend=pstart;
- else{
- pend=strchr(++pstart,'"');
- return-1;
- HasQoute=true;
- intlen=pend-pstart;
- switch(Conf.Element){
- caseEM_LSN_MMSC_PORT:
- Conf.MMSC_LISTEN_PORT=atoi(pstart);
- break;
- caseEM_LSN_CLN_PORT:
- Conf.CLIENT_LISTEN_PORT=atoi(pstart);
- break;
- caseEM_SENDREPEAT:
- Conf.MMS_SUBMIT_REPEATTIME=atoi(pstart);
- caseEM_MMSC_IP:
- return-1;
- strncpy(Conf.MMSC_IPADDR,153); background-color:inherit; font-weight:bold">sizeof(Conf.MMSC_IPADDR)
- ?sizeof(Conf.MMSC_IPADDR):len);
- caseEM_MMSC_PORT:
- Conf.MMSC_PORT=atoi(pstart);
- caseEM_MMSC_ROOT:
- strncpy(Conf.MMSC_ROOT,153); background-color:inherit; font-weight:bold">sizeof(Conf.MMSC_ROOT)?
- sizeof(Conf.MMSC_ROOT):len);
- caseEM_FROM:
- strncpy(Conf.MMSC_FROMADDR,153); background-color:inherit; font-weight:bold">sizeof(Conf.MMSC_FROMADDR)?
- sizeof(Conf.MMSC_FROMADDR):len);
- caseEM_VASPID:
- strncpy(Conf.MMSC_VASP_ID,153); background-color:inherit; font-weight:bold">sizeof(Conf.MMSC_VASP_ID)?
- sizeof(Conf.MMSC_VASP_ID):len);
- caseEM_VASID:
- strncpy(Conf.MMSC_VAS_ID,153); background-color:inherit; font-weight:bold">sizeof(Conf.MMSC_VAS_ID)?
- sizeof(Conf.MMSC_VAS_ID):len);
- caseEM_AUTHNAME:
- strncpy(Conf.MMSC_LOGIN_NAME,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> len>sizeof(Conf.MMSC_LOGIN_NAME)?
- sizeof(Conf.MMSC_LOGIN_NAME):len);
- caseEM_AUTHPWD:
- strncpy(Conf.MMSC_LOGIN_PWD,153); background-color:inherit; font-weight:bold">sizeof(Conf.MMSC_LOGIN_PWD)?
- sizeof(Conf.MMSC_LOGIN_PWD):len);
- default:
- return0;
- /*----------------------------------------------------------------------
- *xml解析函数,0); background-color:inherit">*以下参数说明
- *data是使用XML_SetUserData设置的参数,expat不进行处理,会把它交给用户回调函数处理
- *el是元素名
- *attr是属性-值列表,样子为attr[0]=attr[1],最后一个是NULL
- *----------------------------------------------------------------------*/
- voidXMLCALL
- xmlstart(char**attr)
- //当碰到xml元素的开始标志时会调用这个函数,可以看打印显示的结果
- printf("startelement: