Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4204352
  • 博文数量: 176
  • 博客积分: 10059
  • 博客等级: 上将
  • 技术积分: 4681
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-24 12:27
文章分类

全部博文(176)

文章存档

2012年(1)

2011年(4)

2010年(14)

2009年(71)

2008年(103)

分类: C/C++

2009-01-09 17:03:23


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 \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'.

阅读(4263) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~