minixml开源库的使用

2 篇文章 0 订阅

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;
}

解析结果:

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值