Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1517643
  • 博文数量: 114
  • 博客积分: 10010
  • 博客等级: 上将
  • 技术积分: 1357
  • 用 户 组: 普通用户
  • 注册时间: 2006-11-19 18:13
文章分类
文章存档

2010年(8)

2009年(9)

2008年(27)

2007年(62)

2006年(8)

我的朋友

分类: WINDOWS

2007-12-02 14:14:11

北京理工大学  20981  陈罡
expat xml解析库是一个非常强大的xml解析库,有了它的支持可以将很多参数设置或者内容编排、组织都集成到程序中去。5mbox的杂志内容解析、显示的基础就是expat解析库。目前,我已经让这个库可以在s60 2nd, 3rd以及moto mobilinux上面顺利运行了,还差win mobile平台和uiq平台,就基本上都有了。
 
这次借助开发win mobile5的东风,既frame buffer库、jpeg/png/gif库之后,就把expat库给移植上去。在我的概念里面,写得好的c、c++代码要比java的代码可移植性更高!
 
简单的看了一下,expat 2.0主要有用的文件有5个,它们分别是:
xmlparse.c    : 定义了dtd的支持和外部XML_Parser的函数
xmlrole.c     : 定义了关键字和内容列表什么的
xmltok.c      : 这个就是解析部分的包装了,呵呵,难得作者用c语言实现了所谓的"vtable"虚拟函数表
xmltok_impl.c : 这个是对普通xmltag的解析的实现
xmltok_ns.c   : 这个是对名字空间的解析的实现
 
第一步,需要把原有的.c改为.cpp文件,然后在.h中,把必要的声明部分都加入:
#ifdef __cplusplus
extern "C" {
#endif
....声明部分代码
#ifdef __cplusplus
}
#endif
 
然后就是编译,会发现有一些地方会出现类型不对的问题,这主要是expat的作者用enum来表示这些变量了(而不是用defene),而c++的编译器对类型检查非常严格,因此会出这些问题。强制类型转换一下,然后
再一些没有初始化的变量上把初始值加上。这样就没有警告了。
 
第二步,发现一些奇特的错误如下所示:
\expat\xmltok_impl.c(90) : error C2061: syntax error : identifier 'scanComment'
\expat\xmltok_impl.c(90) : error C2059: syntax error : ';'
\xmltok_impl.c(90) : error C2059: syntax error : 'type'
\expat\xmltok_impl.c(128) : error C2061: syntax error : identifier 'scanDecl'
\expat\xmltok_impl.c(128) : error C2059: syntax error : ';'
\expat\xmltok_impl.c(128) : error C2059: syntax error : 'type'
\expat\xmltok_impl.c(175) : error C2061: syntax error : identifier 'checkPiTarget'
\expat\xmltok_impl.c(175) : error C2059: syntax error : ';'
\expat\xmltok_impl.c(175) : error C2059: syntax error : 'type'
\expat\xmltok_impl.c(220) : error C2061: syntax error : identifier 'scanPi'
\expat\xmltok_impl.c(220) : error C2059: syntax error : ';'
\expat\xmltok_impl.c(220) : error C2059: syntax error : 'type'
\expat\xmltok_impl.c(282) : error C2061: syntax error : identifier 'scanCdataSection'
\expat\xmltok_impl.c(282) : error C2059: syntax error : ';'
\expat\xmltok_impl.c(282) : error C2059: syntax error : 'type'
等等,类似这样的错误。
 
这个错误是如何引起的呢?
仔细看xmltok.c文件,就会发现它有#include "xmltok_impl.c",这是什么意思呢?
原来,作者是靠#include把xmltok_impl.c里面的函数“集成”到xmltok.c中使用。
从vs2005的输出看来,似乎不支持这种在一个.cpp文件中#include另外一个.cpp文件的方法。
通过源代码浏览可以看出,作者用xmltok.c这个文件include了xmltok_impl.c和xmltok_ns.c才会
出现上述的定义问题。
 
解决的方法是,注释掉这个#include "xmltok_impl.c"以及#include "xmltok_ns.c",然后把这两个
.c文件的内容直接复制到xmltok.c里面#include这两个.c的相应位置。重新编译就可以通过了。
 
expat库的基本使用方法如下:
#include
#include "xmlparse.h" // 这是v1.0版的expat的头文件
#include "expat.h"    // 这是v2.0版的expat的头文件
 
//tag中的字符处理函数
void CharacterDataHandler(void *userData, const XML_Char *s, int len)
{
  char* str = (char*)malloc (len + 1);
  strncpy (str, s, len);
  puts (str);
}
 
// tag的开头处理函数
void startElement(void *userData, const char *name, const char **atts)
{
  int i;
  int *depthPtr = userData;
  for (i = 0; i < *depthPtr; i++)
    putchar('\t');
  //puts(name);
  printf ("XML: <%s", name);
  i = 0;
  while (atts[i] && *atts[i] && atts[i][0] != 0)
  {
    if (i % 2)
    {
      printf ("=");
      printf ("\"%s\"", atts[i]);
    }
    else
    {
      printf (" ");
      printf ("%s", atts[i]);
    }
   
    i++;
  }
  printf (">\n");
  *depthPtr += 1;
}
 
// tag的结束处理函数
void endElement(void *userData, const char *name)
{
  int *depthPtr = userData;
  *depthPtr -= 1;
}
 
int main()
{
  char buf[BUFSIZ];
  // 创建XML_Parser对象
  XML_Parser parser = XML_ParserCreate(NULL);
  int done;
  int depth = 0;
  // 设置自定义数据
  XML_SetUserData(parser, &depth);
  // 设置tag的处理函数
  XML_SetElementHandler(parser, startElement, endElement);
  // 设置tag中包含的字符处理函数
  // 例如:这部分字符
  XML_SetCharacterDataHandler(parser, CharacterDataHandler);
  // 这个循环就是多次load文件中的xml数据,然后处理
  do {
    size_t len = fread(buf, 1, sizeof(buf), stdin);
    done = len < sizeof(buf);
    if (!XML_Parse(parser, buf, len, done)) {
      fprintf(stderr,
       "%s at line %d\n",
       XML_ErrorString(XML_GetErrorCode(parser)),
       XML_GetCurrentLineNumber(parser));
      return 1;
    }
  } while (!done);
  // 最后不要忘记释放这个xml解析器的对象
  XML_ParserFree(parser);
  return 0;
}
为了后来人能够不必象我一样在往嵌入式系统中修改和移植expat遇到这么多麻烦的问题,加之expat本身
就是开源的软件。我打算开放这个expat v2.0 for win mobile 5的源代码。
希望能够对各位有用!
文件: expat_wm5_port.rar
大小: 69KB
下载: 下载

注意,这个移植不是生成dll或者lib的,而是直接可以加入到工程中的代码。使用方法是在win mobile中添加新的目录,然后把整个expat目录中的文件都添加进去,然后在使用的地方加入#include "expat.h"。然后在vs2005中添加相关的include目录,就可以在vs2005中编译和运行了。

祝大家好运!

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

chinaunix网友2010-07-02 14:08:12

楼主您好!能不能给我一份s60 3rd的expat版本 jxgjxgok@126.com先谢谢

chinaunix网友2010-07-02 14:07:26

楼主您好!能不能给我一份s60 3rd的expat版本

chinaunix网友2008-03-14 09:16:39

楼主,你好。我按照你的方法使用,在vc2005下添加了全部的文件,怎么编译都没有通过呢?能否给一个工程例子?谢谢 qiqi0120@sina.com

chenwayne2008-03-05 22:54:32

那个syexpat2是没有问题的,检查你的调用代码以及包含的lib文件。 这个dll我已经在3rd上用到项目中去了,没问题。

pirate_wb2008-03-05 21:46:59

陈罡人不错,呵呵,今天就把代码给我发过来了。 很遗憾的是你给我的版本跟之前我用的一个一样,虽然成功编译出dll,但是在应用中只要调用任何一个导出函数就会进不了应用,报epoc.exe异常,郁闷。。。