4、SAX方式使用iksemel
笔者的习惯,先上例子程序(直接来自iksemel的doc):
//test.c
#include <stdio.h>
#include <iksemel.h>
int pr_tag (void *udata, char *name, char **atts, int type)
{
switch (type) {
case IKS_OPEN:
printf ("TAG <%s>\n", name);
break;
case IKS_CLOSE:
printf ("TAG %s>\n", name);
break;
case IKS_SINGLE:
printf ("TAG <%s/>\n", name);
break;
}
if (atts) {
int i = 0;
while (atts[i]) {
printf (" ATTRIB %s='%s'\n", atts[i], atts[i+1]);
i += 2;
}
}
return IKS_OK;
}
enum ikserror pr_cdata (void *udata, char *data, size_t len)
{
int i;
printf ("CDATA [");
for (i = 0; i < len; i++)
putchar (data[i]);
printf ("]\n");
return IKS_OK;
}
int main (int argc, char *argv[])
{
iksparser *p;
p = iks_sax_new (NULL, pr_tag, pr_cdata);
switch (iks_parse (p, argv[1], 0, 1)) {
case IKS_OK:
puts ("OK");
break;
case IKS_NOMEM:
puts ("Not enough memory");
exit (1);
case IKS_BADXML:
puts ("XML document is not well-formed");
exit (2);
case IKS_HOOK:
puts ("Our hooks didn't like something");
exit (2);
}
iks_parser_delete (p);
return 0;
}
|
编译:
gcc -o test test.c -liksemel
这个可能会出现错误,因为我们前面安装 iksemel 的时候选择的自己设定的路径,不是系统默认路径。
可以通过下面方法解决:
gcc -o test test.c -liksemel -I/data/soft/iksemel-1.3/include -L/data/soft/iksemel-1.3/lib
通过"-I"添加头文件的搜索路径,通过"-L"添加库文件的搜索路径,通过"-l"添加动态链接库的文件名。
下面运行:
./test "
Hello
World"
./test "
"
可能会出现下面的情况:
./test: error while loading shared libraries: libiksemel.so.3: cannot open shared object file: No such file or directory
这个问题因为刚刚编译的时候没有选择静态编译,那么按照默认的编译就动态编译的。
动态编译后,由于可执行文件在运行时要调用系统库文件,
那么沿着系统默认的库文件搜索路径搜索,就可能找不到我们现在所需的库文件。
致使出现 "error while loading shared libraries" 等错误。
我们可以这样解决:
方法一:静态编译
在编译时加上 -static 参数
方法二:重新配置系统环境变量 LD_LIBRARY_PATH
这时需要指定 libiksemel.so.0 库文件的路径,也就是配置系统环境变量 LD_LIBRARY_PATH ,
使系统能够找到 libiksemel.so.0 。
例如:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/data/soft/iksemel-1.3/lib
这样就应该不会又问题。
[root@localhost xmltest]# ./test "
Hello
World"
TAG
CDATA [Hello]
TAG
CDATA [World]
TAG OK
[root@localhost xmltest]# ./test "
"
TAG
ATTRIB a='12'
ATTRIB b='42'
OK
主要用到的函数的介绍:
iksparser* iks_sax_new (void* USER_DATA, iksTagHook*
TAGHOOK, iksCDataHook* CDATAHOOK);
该函数分配内存和初始化一个 SAX 解析器。如果分配内存失败,返回NULL。
int iks_parse (iksparser* PRS, char *DATA, size_t LEN, int
FiNiSH);
这个函数处理XML文本数据。
iksparser* PRS:上一个函数的返回指针。
char *DATA:XML文本数据
size_t LEN:数据长度。如果等于0,那么DATA必须为一个空字符串
int FiNiSH:如果为0,那么这个函数等待更多的数据输入。如果想处理一次就退出,那么可以这样调用:
iks_parse (my_parser, NULL, 0, 1);
返回值:
`IKS_OK'
OK,没有任何问题
`IKS_NOMEM'
内存不足
`IKS_BADXML'
XML文件数据格式不对
`IKS_HOOK'
自定义的hook函数决定的错误。
void iks_parser_delete (iksparser* PRS);
释放相关的内存。
iksTagHook
int iksTagHook (void* USER_DATA, char* NAME, char** ATTS, int TYPE);
这个函数是标记( Tag )分析器。 NAME 是标记的名字。如果没有属性,ATTS = NULL,
否则ATTS是一个二维数组指针,指向属性(char*)数组。
TYPE 值:
`IKS_OPEN'
开始标记tag, i.e.
`IKS_CLOSE'
结束标记tag, i.e. `IKS_SINGLE'
独立标记 tag, i.e.
iksCDataHook
int iksCDataHook (void* USER_DATA, char* DATA, size_t LEN);
该函数用来处理数据的。
DATA is a pointer to the character data. Encoding is UTF-8 and it
isn't terminated with a null character. Size of the data is given
with LEN in bytes. This function can be called several times with
smaller sized data for a single string. If return value isn't
`IKS_OK', it is passed immediately to the caller of the
`iks_parse'.
阅读(4375) | 评论(0) | 转发(0) |