2026年11月2日 · 今日 0 帖 · 会员 6.1万 · 主题 17.4万
登录 · 注册 · 游客,欢迎随便逛逛
返回版块
1000
Lv9有为九子能等级图标
勋章勋章勋章勋章勋章
帖子
9.3万
回复
2,089
积分
60.3万
注册
2006-12-06
[怀旧国机]

C语言实现的XML解析器

[复制链接]
查看 208 回复 0
楼主 发表于 | 只看该作者
2 人收藏

最近做嵌入式开发,板子上面需要有解析XML的功能,理所当然地我就去网上找开源的来用。结果找来的要不是C++的,要不就是超级复杂的。像libxml,我统计了下解析一个40几KB的XML文件,居然动态申请内存100多次,对于没有mmu功能的arm7,真是无福消受了。

所以,我只能自己写一个来用了。

我写的这个xml解析器,非常简单,核心代码只有600多行。当然,功能也相对弱些,只支持ansi编码的xml文件,只能解析,不能生成。

整个解析器只用到了 若干条 EBNF文法 和 一个DFA状态机 (用来跳过注释的), 采用了递归下降的分析方法.

整个解析过程没有动态申请内存,不会造成内存碎片(特别适应于没有mmu的设备), 当然,在开始解析之前,还是需要提供一片缓冲给解析器用的,最后生成的XML树,就放在这片缓冲里面.

接口如下:

/******************************************************

/* minixml.h

/*

/* author:@#$$$$$$$$$$$$$$$$%^&*

/*

/* about:

/* 该文件提供根据解析XML文件功能

/*

/*

/* sample:

/*

/* 支持平台: windows , linux 2.4,2.6 uclinux

/* 表示是输入参数

/* 表示是输出参数

/******************************************************/

#ifndef _MINIXML_H_08_17_

#define _MINIXML_H_08_17_

#define _CRT_SECURE_NO_DEPRECATE

#if defined (__cplusplus) || defined (c_plusplus)

extern “C“ {

#endif

struct _MINI_XML_ATTRI;

struct _MINI_XML_NODE;

/* 记录一个属性信息 */

typedef struct _MINI_XML_ATTRI

{

char* name; /* 属性名 */

char* value; /* 属性值 */

struct _MINI_XML_ATTRI* next; /* 指向下一个属性 */

} MINI_XML_ATTRI;

/* 记录一个XML节点信息 */

typedef struct _MINI_XML_NODE

{

char*name; /* 节点名 */

char* value; /* 节点值 */

MINI_XML_ATTRI* attri_list; /* 属性列表 */

struct _MINI_XML_NODE* parent; /* 父节点 */

struct _MINI_XML_NODE* child; /* 子节点, 若没有则为空 */

struct _MINI_XML_NODE* next; /* 同层下一节点 */

} MINI_XML_NODE;

  

/

说明 : 解析XML文件,返回XML的根节点

参数 :

: xml xml文件路径

: buffer 供解析用的缓冲

: buffer_len 缓冲大小(单位:字节)

: error_reason 执行出错时保存错误原因

: root XML的根节点

返回 : 成功 返回0 ,失败返回 -1

说明 :

: 问 :供解析用的缓冲应该取多大比较合适呢?

: 答 :供解析用的缓冲主要用来存放XML树, 所以 buffer_len >= (XML文件的大小) * 2 即可

:

int mini_parse_xml (char* xml,

char* buffer, int buffer_len,

char error_reason,

MINI_XML_NODE** root);

/

说明 : 查找特定节点的子节点

参数 :

: father 父结点

: name 子孩子节点名

: child 子节点

int mini_find_child (MINI_XML_NODE* father, char* name, MINI_XML_NODE** child);

/

说明 : 查找特定节点的属性值

参数 :

: node 节点

: name 属性名

: value 属性值

int mini_find_attribute (MINI_XML_NODE* node, char* name, char** value);

/

说明 : 打印XML树,供调试用

int mini_print_tree (MINI_XML_NODE* root , int layer);

#if defined (__cplusplus) || defined (c_plusplus)

}

#endif

#endif

登录回复

登录后可以回复这个帖子。旧账号可使用原密码登录。

登录 注册新号
← 返回版块