minixml是一款轻量级、可供C语言调用的XML文件创建、解析的开源库,安装包https://github.com/michaelrsweet/mxml/releases/tag/v3.1可以下载。 使用时需要包含头文件<mxml.h>,编译时需要加上-lmxml链接动态库。
下面是一些常用接口:
生成XML文件接口:
1. 创建一个新的xml文件
mxml_node_t *mxmlNewXML(const char *version);
//返回新创建的xml文件结点,默认编码utf-8
//参数为版本号,一般是"1.0"
2. 删除结点的内存
void mxmlDelete(mxml_node_t *node);
3. 添加一个新的结点
mxml_node_t *mxmlNewElement(mxml_node_t *parent, const char *name);
//参数1为父结点,参数2为新增加的标签名
4.设置结点的属性
void mxmlElementSetAttr(mxml_node_t *node, const char *name, const char *value);
//参数1被设置的结点名,参数2位属性名,参数3为属性内容
5.创建结点的文本内容
mxml_node_t *mxmlNewText(mxml_node_t *parent, int whitespace, const char *string);
//参数1为结点地址,参数2为是否有空格,参数3位文本内容
6.保存结点到xml文件
int mxmlSaveFile(mxml_node_t *node, FILE *p, mxml_save_cb_t cb);
//参数1为根节点,参数2为该文件保存地址的文件指针,参数3为回调函数, 默认MXML_NO_CALLBACK
下面给出一个例子:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <mxml.h>
/*
* <china>
* <city>
* <name "首都" = "Yes">"北京"</name>
* <area>16410平方公里</area>
* <population> </population>
* <GDP> </GDP>
* </city>
* ...
* ...
* </china>
*
* 级别排序: 文件头 -> china -> city -> 子城市
* 创建文件头 - mxmlNewXML
* 创建标签 - mxmlNewElement
* 文本内容 - mxmlNewText
* 属性设置 - mxmlElementSetAttr
*/
int main(){
//文件头
mxml_node_t *root = mxmlNewXML("1.0");
//根标签,创建新结点 -- china
mxml_node_t *china = mxmlNewElement(root, "china");
//china的子标签,创建新结点 -- city
mxml_node_t *city = mxmlNewElement(china, "city");
mxmlElementSetAttr(city, "capital", "Yes"); //<city 首都="Yes">
/* 北京 */
mxml_node_t *info = mxmlNewElement(city, "name");
mxmlNewText(info, 0, "北京"); //文本内容设置
//文本内容
info = mxmlNewElement(city, "area");
mxmlNewText(info, 0, "16410平方公里"); //文本内容设置
info = mxmlNewElement(city, "population");
mxmlNewText(info, 0, "2171万");
info = mxmlNewElement(city, "GDP");
mxmlNewText(info, 0, "24541亿");
/* 东京 */
city = mxmlNewElement(china, "city");
mxmlElementSetAttr(city, "capital", "NO");
info = mxmlNewElement(city, "name");
mxmlNewText(info, 0, "东京");
info = mxmlNewElement(city, "area");
mxmlNewText(info, 0, "2188平方公里");
info = mxmlNewElement(city, "population");
mxmlNewText(info, 0, "3670万");
info = mxmlNewElement(city, "GDP");
mxmlNewText(info, 0, "31700亿");
// 将数据保存到磁盘
FILE *p = fopen("china.xml", "w");
mxmlSaveFile(root, p, MXML_NO_CALLBACK);
fclose(p);
mxmlDelete(root); //释放根节点的内存
return 0;
}
xml文件如下,注意到:由于是没有换行的,所以并不是很美观,但是更方便下面的解析
**
解析XML解析常用接口
**
1. 将xml文件加载进来
mxml_node_t *mxmlLoadFile(mxml_node_t *top, FILE *fp, mxml_type_t(*cb)(mxml_node_t*));
//参数1一般为NULL,参数2为文件指针,参数3默认MXML_NO_CALLBACK
2. 获取结点的属性
const char *mxmlElementGetAttr(mxml_node_t *node, const char *name);
//参数1为带属性的节点的地址,参数2位属性名
3, 获取指定结点的文本内容
const char* mxmlGetText(mxml_node_t *node, int *whitespace);
//参数1为结点的地址,参数2为是否有空格
3. 跳转到下一个结点
mxml_node_t *mxmlWalkNext(mxml_node_t *node, mxml_node_t *top, int descend);
**descend参数为搜索的规则:
MXML_NO_DESCEND:搜索同层级
MXML_DESCEND_FIRST:搜索下一层级的第一个结点
MXML_DESCEND:一直向下搜索
4.查找结点
mxml_node_t *mxmlFindElement(mxml_node_t *node, mxml_node_t *top, const char* name, const char *attr, const char *value, int descend);
//参数1为当前结点,参数为根结点,参数3 4 5为查找结点的标签名、标签属性、标签属性内容。最后一个同上
**
下面开始解析上面已经创建好的xml文件:
**
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <mxml.h>
using namespace std;
int main(){
FILE* fp = fopen("china.xml", "r");
mxml_node_t *root = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
//找到第一个结点China
mxml_node_t *china = mxmlFindElement(root, root, "china", NULL,
NULL, MXML_DESCEND);
while(china){
//向下移动结点
mxml_node_t *city = mxmlWalkNext(china, root, MXML_DESCEND);
while(city){
cout << " 是否首都: " << mxmlElementGetAttr(city, "capital") << endl;
mxml_node_t *node = mxmlWalkNext(city, root, MXML_DESCEND_FIRST);
cout << " name: " << mxmlGetText(node, 0) << endl; //0表示没有空格
node = mxmlWalkNext(node, root, MXML_NO_DESCEND);
cout << " area: " << mxmlGetText(node, 0) << endl;
node = mxmlWalkNext(node, root, MXML_NO_DESCEND);
cout << " population: " << mxmlGetText(node, 0) << endl;
node = mxmlWalkNext(node, root, MXML_NO_DESCEND);
cout << " GDP: " << mxmlGetText(node, 0) << endl;
cout << " ====================================" << endl;
city = mxmlFindElement(city, root, "city", NULL, NULL, MXML_NO_DESCEND);
}
china = mxmlFindElement(china, root, "china", NULL, NULL, MXML_NO_DESCEND); //两个NULL所在参数为:属性名,属性内容
}
mxmlDelete(root);
fclose(fp);
return 0;
}
解析结果: