在XML大行其道的今天,想不使用xml还真是比较困难的,不管是新锐java、c#等,就算是原始的c也逃不过。
不管是新系统还是老系统,总是要进行数据交换,而现阶段的最佳选项往往是xml。
很不幸的是c/c++的标准库里面并没有xml相关的实现,所以往往的要另行选择第三方库,当然也可以自己简单
的写一个,只满足自己需求的迷你库,或者连库都称不上,但是够用就好
。
用过的最出名的xml库,莫过于gnome的子项目libxml2了,使用纯C写的,功能强大,应用成熟,而且文档也很完
整,虽然是E文的,花半天时间还是整得通的;还有一大批人喜欢用tinyXml,这个我没有用过,所以不好评价,如果
我没有记错的话,tinyXml应该是用c++写的,本人有人习惯,如果使用第三方库,倾向于使用纯C库,一是比较清楚,
而且一般应用比较久比较成熟,最重要的是,我们那可怜的aix5.2只装了c的编译器。晕,说屁话已经成为我的一种
习惯 了,离题严重。
综上所述,libxml2是最佳选择,但是libxml2有个相当严重的问题,不支持GBK以及GB2312,而且恰恰GB2312
是我们最常用的编码,对我们而言就是半残废了,虽然Google一下,还是有一些哥们自己给加上了这个编码的支持,
但是感觉就是不爽,如果哪一天libxml2发了新版,修正了哪个bug,是不是我们又要再改一次呢?在还没有正式支持之前
还是算了吧!
屁话又说了一堆,无非是想推销我花了两天时间写的xml解析!
优点是用法简单,纯C写,文件小,跟那个libxml2比起来,咱这只是个张小泉,五毛钱一个的剪刀,不过相信不是所有的
人都需要使用切割器去剪头发的,所以,相信还是有点市场。不过缺点也是有的,毕竟没怎么优化,在解析xml的大文件时
效率相当低下,懒得花时间去整他了,毕竟这也只是个张小泉小剪刀!
介绍一下最简单的几个函数
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
tuobao_xml_query.h
/*节点*/
struct _xmlnode {
char *keyName; /*节点名称*/
char *value; /*节点值*/
struct _xmlnode *child; /*子节点*/
struct _xmlnode *attribute; /*属性节点*/
struct _xmlnode *next; /*兄弟队列 下一个*/
struct _xmlnode *lastchild; /*最小的孩子节点*/
};
/*分配一个节点内存*/
int tuobao_xmlnode_init(xmlnode** ppNode);
/*设置节点键名键值,(很遗憾:AIX5.2下不支持默认值的写法)*/
int tuobao_xmlnode_set(xmlnode *pn,const char *pstrKey,const char *pstrValue=NULL);
/*解析XML,(注意:没有对文档声明<?xml
>做处理喔)*/
int tuobao_xmlnode_parse(xmlnode** lpNode,const char *strXml);
/*将结构体转为字符串*/
int tuobao_xmlnode_to_str(xmlnode*,char **,BOOL bBrother= FALSE /*是否打印兄弟节点*/);
/*释放内存*/
int tuobao_xmlnode_free(xmlnode*);
/*给定的父结点下增加子节点*/
xmlnode *tuobao_xmlnode_addchild(xmlnode*,const char* pstrKey,const char* pstrValue=NULL);
/*给指定节点增加属性*/
xmlnode *tuobao_xmlnode_addattribute(xmlnode*,const char*,const char*);
/*简单的路径查找支持*/
xmlnode *tuobao_xmlnode_findpath(xmlnode *parent,const char *path);
/*返回指定子节点值,NULL则为空白*/
const char *tuobao_xmlnode_childvalue(xmlnode *parent,const char *key);
/*返回节点的指点属性的值*/
char *tuobao_xmlnode_atrr_value(xmlnode *pN,const char *attrKey);
写个简单的demo
#include <stdlib.h>
#include <string.h>
#include <tuobao_xml_query.h>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
int main ()
{
xmlnode *parent,*node;
char *outXml;
parent = NULL;
outXml = NULL;
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//*构造xml字符串*/
tuobao_xmlnode_init(&parent);
tuobao_xmlnode_set(parent,"books");
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//*增加一个子节点*/
node = tuobao_xmlnode_addchild(parent,"book");
tuobao_xmlnode_addchild(node,"name","深入浅出MFC");
tuobao_xmlnode_addattribute(node,"price","88.8");
node = tuobao_xmlnode_addchild(parent,"book");
tuobao_xmlnode_addchild(node,"name","ASP.NET组件设计");
tuobao_xmlnode_addattribute(node,"price","108.8");
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//*转成字符串*/
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if(tuobao_xmlnode_to_str(parent,&outXml))
{
printf("toString失败!\n");
return 1;
}
printf("生成XML:\n%s\n",outXml);
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//*释放掉结构体内存*/
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if(parent != NULL)
{
tuobao_xmlnode_free(parent);
parent = NULL;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//*解析XML*/
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if(tuobao_xmlnode_parse(&parent,outXml))
{
printf("解析失败\n");
return 1;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//*遍历一下节点*/
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
node = tuobao_xmlnode_findpath(parent,"books/book");/**//* 以层级键名的方式查找*/
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while(node != NULL)
{
printf("<<%s>> 价格%s\n",
tuobao_xmlnode_childvalue(node,"name"),
tuobao_xmlnode_atrr_value(node,"price"));
node = node->next;
}
if(outXml) free(outXml);
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//*释放掉结构体内存*/
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if(parent != NULL)
{
tuobao_xmlnode_free(parent);
parent = NULL;
}
return 0;
}
算了,需要的人直接下文件吧
https://files.cnblogs.com/linbc/tuobao_xml_query.rar
使用过程当中,有何不解,或者发现了bug,请留言
谢谢捧场!