其实expat是php内置的一个xml解析器,当然也可以在其他很多语言中使用,这里主要在win32 plat下的c/c++下使用expat。
expat是基于sax来进行xml解析而不是dom解析。因此,在expat中设置了很多的回调来处理。
在win32下使用,可以http://sourceforge.net/projects/expat/下载,里面有win32版本,下载下来的是一个安装包,直接安装,
安装之后,在安装目录例如C:\Expat-2.0.0下有Docs libs source 等几个目录,其中libs目录下放了4个文件,分别是libexpat
的Ansi和Unicode的dll和对应lib。在source下,有 example tests lib等目录,其中lib目录下是expat的源代码(头文件和实现文件)
以及dsp文件。里面有编译生成动态链接库的工程文件expat.dsp以及编译成为静态库的expat_static.dsp。expat.dsp编译出来的动态区
名称为libexpat.dll(libexpat.lib);静态库工程expat_static.dsp编译出来的静态库名称为:libexpatMT.lib。
在source\example目录下有参考代码。
其中看看elements 这个example就ok了。
对于一个简单的xml文件,我们
main(int argc, char *argv[])
{
XML_Parser p = XML_ParserCreate(NULL);
XML_SetCharacterDataHandler(p,charhandler);
XML_SetElementHandler(p, start, end);
for (;;) {
int done;
int len;
len = fread(Buff, 1, BUFFSIZE, stdin);
if (ferror(stdin)) {
fprintf(stderr, "Read error\n");
exit(-1);
}
done = feof(stdin);
if (XML_Parse(p, Buff, len, done) == XML_STATUS_ERROR) {
fprintf(stderr, "Parse error at line %" XML_FMT_INT_MOD "u:\n%s\n",
XML_GetCurrentLineNumber(p),
XML_ErrorString(XML_GetErrorCode(p)));
exit(-1);
}
printf( " depth = %d \n",Depth);
if (done)
break;
}
return 0;
}
其中XML_SetElementHandler设置回调,处理element节点;XML_SetCharacterDataHandler设置回调用于处理text节点
一般来说有了这两个我们就可以处理了,例如下面的一个xml文件
<?xml version="1.0"?>
<xmlRoot price="">
<YEAR Now="2005">
<QUARTER1>2005</QUARTER1>
</YEAR>
</xmlRoot>
处理到xmlRoot节点的时候,会调用XML_SetElementHandler设置的回调函数,我们可以从回调函数中获取节点名称,节点的
属性列表,包括各个属性名称和对应的属性值。这里就可以获取到一个属性price,值为空。
继续下面的处理,当处理到QIARTER1时,会调用XML_SetCharacterDataHandler设置的回调函数获取text节点值。
char buf[100]={0};
static void XMLCALL charhandler(void *userData,const XML_Char *s, int len)
{
if(len!=0)
{
memcpy(buf,s,len);
buf[len] = '\0';
rintf("%s " ,buf);
}
}
注意,这里的s不是以\0结束的。