随笔-167  评论-8  文章-0  trackbacks-0

互联网发展得很快,都是源自于使用了超文本的表达方式。比如你查看一篇文章,看到不懂的关键字,就可以通过链接去查看它的内容,看完之后再回来接着看原来的东西,这样比较适合学习的方式。使用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 XML解析器之前,先来仔细地分析一下怎么样使用expat库的小例子,看看具体调用了那些接口函数,是否会很复杂的呢?‘它的例子程序如下:
#001 /*****************************************************************
#002   * outline.c
#003   *
#004   * Copyright 1999, Clark Cooper
#005   * All rights reserved.
#006   *
#007   * This program is free software; you can redistribute it and/or
#008   * modify it under the same terms as Perl.
#009   *
#010   * Read an XML document from standard input and print an element
#011   * outline on standard output.
#012   */
#013
#014
 
下面包括输出文件和库文件头。
#015 #include <stdio.h>
#016 #include "xmlparse.h"
#017
 
定义缓冲区的大小。
#018 #define BUFFSIZE   8192
#019
 
创建一个缓冲区。
#020 char Buff[BUFFSIZE];
#021
#022 int Depth;
#023
 
下面定义一个XML元素开始处理的函数。
#024 void
#025 start(void *data, const char *el, const char **attr) {
#026    int i;
#027
#028    for (i = 0; i < Depth; i++)
#029      printf(" ");
#030
#031    printf("%s", el);
#032
#033    for (i = 0; attr[i]; i += 2) {
#034      printf(" %s='%s'", attr[i], attr[i + 1]);
#035    }
#036
#037    printf("\n");
#038    Depth++;
#039 } /* End of start handler */
#040
 
下面定义一个XML元素结束调用的函数。
#041 void
#042 end(void *data, const char *el) {
#043    Depth--;
#044 } /* End of end handler */
#045
 
程序入口点。
#046 void
#047 main(int argc, char **argv) {
 
创建一个XML分析器。
#048    XML_Parser p = XML_ParserCreate(NULL);
 
下面判断是否创建XML分析器失败。
#049    if (! p) {
#050      fprintf(stderr, "Couldn't allocate memory for parser\n");
#051      exit(-1);
#052    }
#053
 
下面设置每个XML元素出现和结束的处理函数。这里设置start为元素开始处理函数,end元素结束处理函数。
#054    XML_SetElementHandler(p, start, end);
#055
 
循环分析所有XML文件。
#056    for (;;) {
#057      int done;
#058      int len;
#059
 
调用函数fread从文件里读取数据到缓冲区Buff里。
#060      len = fread(Buff, 1, BUFFSIZE, stdin);
 
读取文件出错就退出。
#061      if (ferror(stdin)) {
#062        fprintf(stderr, "Read error\n");
#063        exit(-1);
#064      }
 
判断是否读取文件到结束。
#065      done = feof(stdin);
#066
 
调用库函数XML_Parse来分析缓冲区Buff里的XML数据。
#067      if (! XML_Parse(p, Buff, len, done)) {
#068        fprintf(stderr, "Parse error at line %d:\n%s\n",
#069          XML_GetCurrentLineNumber(p),
#070          XML_ErrorString(XML_GetErrorCode(p)));
#071        exit(-1);
#072      }
#073
 
如果分析文件到结尾位置,或者出错,就可以退出循环处理。
#074      if (done)
#075        break;
#076    }
#077 } /* End of main */
#078
#079
#080
 
通过上面调用库函数XML_ParserCreate、XML_SetElementHandler、XML_Parse等三个函数就完成了XML的分析过程,这样使用起来真是太简单了,看到expat库的威力无穷。
 
如果需要了解更多关于expat库的内容,可以参考下面两个网站:
http://expat.sourceforge.net/
http://www.xml.com/pub/a/1999/09/expat/index.html?page=2
 


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/caimouse/archive/2008/05/19/2459566.aspx

posted on 2010-06-16 15:02 老马驿站 阅读(2739) 评论(0)  编辑 收藏 引用 所属分类: c++