zoukankan      html  css  js  c++  java
  • C++中使用Expat解析XML

    本文介绍expat 解析xml的基本方法,如果你希望用最轻量的解析器,请选择TinyXML,它更简单。

    使用expat的原因很多,主要还是因为expat更灵活。习惯了TinyXML,一开始不太习惯expat,分析一下,其实很容易上手的。

    1.回调函数

    以下案例解析xml文件中的elment,attribute和text。expat使用回调方式返回xml数据,解析器解析到一个element及其内部属性后,将调用事先设置好的函数,同样,当element结束和text结束后,也会分别调用对应的函数。

    2.如何处理数据之间的包含关系

    典型的方式是定义三个函数分别处理elment开始(含属性)、element结束和文本内容。回调函数的第一个参数是自定义的,通常用于存储XML文档的上下文信息,用XML_SetUserData可以设置这个参数,下例中传递一个整数指针,以便在每次回调时能知道该元素是第几层元素。

    该参数也可以是一个栈对象的地址,开始一个元素时,将新元素对应的数据压入堆栈,处理下一级元素时,新元素是栈顶元素在子元素,然后处理完了继续把该元素压入堆栈,继续下一级新的子元素。当元素结束后,需要出栈,以便解析下个兄弟元素程时能取到父节点。

    好啦,基本应用还是很简单的,实际上Expat的API函数不多。

    3.如何处理属性

    属性通过ElementHandler回调函数传入,这里有一个char** atts就是属性,这是一个字符指针数组,如果有N个属性,数组大小就是2*N+1,最后一个素组元素为空指针,奇数指针对应属性名称,偶数指针对应属性值(字符串格式)。可以在一个循环中处理多个属性,当遇到空指针时,表示没有更多属性了。

    好啦,先看sample吧:

    #include <stdio.h>
    #include
    "expat.h"


    #pragma warning(disable:4996)


    #define XML_FMT_INT_MOD "l"

    static void XMLCALL startElement(void *userData, const char *name, const char **atts)
    {
    int i;
    int *depthPtr = (int *)userData;
    for (i = 0; i < *depthPtr; i++)
    printf(
    " ");


    printf(name);

    *depthPtr += 1;

    for(i=0;atts[i]!=0;i+=2)
    {
    printf(
    " %s=%s",atts[i],atts[i+1]);
    }

    printf(
    "\n");
    }

    static void XMLCALL endElement(void *userData, const char *name)
    {
    int *depthPtr = (int *)userData;
    *depthPtr -= 1;
    }

    int main(int argc, char *argv[])
    {
    char buf[BUFSIZ]; XML_Parser parser = XML_ParserCreate(NULL);

    int done; int depth = 0;

    XML_SetUserData(parser,
    &depth);

    XML_SetElementHandler(parser, startElement, endElement);

    FILE
    * pFile= argc<2 ?stdin : fopen(argv[1],"rb");

    do
    {
    int len = (int)fread(buf, 1, sizeof(buf), pFile);
    done
    = len < sizeof(buf);

    if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR)
    {
    fprintf(stderr,
    "%s at line %" XML_FMT_INT_MOD "u\n",
    XML_ErrorString(XML_GetErrorCode(parser)),
    XML_GetCurrentLineNumber(parser));
    return 1;
    }
    }
    while (!done);
    XML_ParserFree(parser);
    fclose(pFile);
    return 0;
    }

    4.其他ElementHanlder

    expat还可以设置CData,Comment的handler,另外一些函数本人还没使用过,涉及到更多的xml标准的知识,如果需要,可以参考官方的手册。 

    参考:

    http://www.xml.com/pub/a/1999/09/expat/index.html 

  • 相关阅读:
    Windows Azure Cloud Service (14) 使用Windows Azure诊断收集日志记录数据
    Windows Azure Cloud Service (13) 用Visual Studio 2010 将应用程序部署到Windows Azure平台
    Windows Azure Cloud Service (15) 多个VM Instance场景下如何处理ASP.NET Session
    Windows Azure Storage (5) Windows Azure Drive
    Windows Azure Storage (7) 使用工具管理Windows Azure Storage
    SQL Azure(二) SQL Azure vs SQL Server
    webbrowser的自动提交
    提取视频的背景声音的软件
    Listview列排序的bug原因
    两个奇怪的问题
  • 原文地址:https://www.cnblogs.com/Tue/p/1650258.html
Copyright © 2011-2022 走看看