Mini-Xml 经典实例Demo

欢迎小伙伴的点评✨✨,相互学习、博主将自己研发xml微型服务器的经验与之分享

文章目录

  • 前言
  • 一、使用mxml库编写Xml文件
    • 1.1 经典实例Demo_1
    • 1.2、经典实例Demo_2
    • 1.3、经典实例Demo_3
  • 二、总结


前言

本章将会给大家带来mini-xml的基本实例解析

一、使用mxml库编写Xml文件

mxml 环境配置

1.1 经典实例Demo_1

#include "config.h"
#include "mxml.h"
#include "mxml-private.h"
int main()
{
    mxml_node_t *xml;    /*定义根节点指针*/
    mxml_node_t *data;   /*定义节点指针*/
    mxml_node_t *node;   /*定义节点指针*/
    mxml_node_t *group;  /*定义节点指针*/
    xml = mxmlNewXML("1.0");  /*设置xml版本号*/
    data = mxmlNewElement(xml, "data");  /*设置根节点data*/
    mxmlElementSetAttr(data,"type","val");  /*设置节点data的属性为val*/
    node = mxmlNewElement(data, "node"); /*基于根节点data的基础上新建节点node*/
    mxmlNewText(node, 0, "val1");        /*设置当前节点node的文本为val1*/
    node = mxmlNewElement(data, "node"); /*基于根节点data的基础上新建节点node*/
    mxmlNewText(node, 0, "val2");        /*设置当前节点node的文本为val2*/
    node = mxmlNewElement(data, "node"); /*基于根节点data的基础上新建节点node*/
    mxmlNewText(node, 0, "val3");        /*设置当前节点node的文件为val3*/
    group = mxmlNewElement(data, "group"); /*基于根节点data的基础上新建节点group*/
        node = mxmlNewElement(group, "group_node"); /*基于节点group的基础上新建节点group_node*/
        mxmlNewText(node, 0, "val4");               /*设置当前节点group_node的文本为val4*/
        node = mxmlNewElement(group, "group_node"); /*基于节点group的基础上新建节点group_node*/
        mxmlNewText(node, 0, "val5");               /*设置当前节点group_node的文本为val5*/
        node = mxmlNewElement(group, "group_node"); /*基于节点group的基础上新建节点group_node*/
        mxmlNewText(node, 0, "val6");               /*设置当前节点group_node的文本为val6*/
    node = mxmlNewElement(data, "node");            /*基于根节点data的基础上新建节点node*/
    mxmlNewText(node, 0, "val7");                   /*设置当前节点node的文本为val7*/
    node = mxmlNewElement(data, "node");            /*基于根节点data的基础上新建节点node*/
    mxmlNewText(node, 0, "val8");                   /*设置当前节点node的文本为val8*/
    FILE *fp;                                       /*新建文件流指针 fp*/
    fp = fopen("demo.xml","wb");                    /*新建或者打开demo.xml*/
    mxmlSaveFile(xml,fp,MXML_NO_CALLBACK);          /*将数据保存到文件*/
    fclose(fp);                                     /*关闭文件流指针*/
    mxmlDelete(xml);	                            /*关闭xml根节点*/
    return 0;
}

代码解析:
1、mxml_node_t :XML节点数据类型,其类型为typedef struct mxml_node_s mxml_node_t;
其中mxml_node_s 结构体成员如下:

struct _mxml_node_s			/**** An XML node. ****/
{
  mxml_type_t		type;		/* Node type */
  struct _mxml_node_s	*next;		/* Next node under same parent */
  struct _mxml_node_s	*prev;		/* Previous node under same parent */
  struct _mxml_node_s	*parent;	/* Parent node */
  struct _mxml_node_s	*child;		/* First child node */
  struct _mxml_node_s	*last_child;	/* Last child node */
  _mxml_value_t		value;		/* Node value */
  int			ref_count;	/* Use count */
  void			*user_data;	/* User data */
};

2、mxmlNewXML:创建一个新的 XML 文档树,使用的版本号返回值。
其中mxmlNewXML()声明如下:

mxml_node_t *mxmlNewXML (const char *version);

参数
version:版本号
返回值:新的 “?xml” 节点
3、mxmlNewElement:创建一个新的 XML 元素节点
其中mxmlNewElement()声明如下:

mxml_node_t *mxmlNewElement (
mxml_node_t *parent,
const char *name
);

参数
parent:父节点或MXML_NO_PARENT
name:XML元素名称
返回值:新节点
4、mxmlNewText:创建新的文本分段节点

mxml_node_t *mxmlNewText (
mxml_node_t *parent,
int whitespace,
const char *string
);

参数
parent :父节点或 MXML_NO_PARENT ;
whitespace: 1 = 有前导空格, 0 = 没有空格;
string:字符串、返回值、新节点;
返回值:新节点

5、mxmlSaveFile:保存一个XML节点树到一个文件。

int mxmlSaveFile ( 
    mxml_node_t *node, 
    FILE *fp, 
    mxml_save_cb_t cb 
);

参数
node:准备要写入的节点;
fp:准备写入的文件;
cb :空白回调函数或者MXML_NO_CALLBACK;
编译后生成文件如下:
返回值:成功返回 0,错误返回 -1。
Mini-Xml 经典实例Demo_第1张图片
此时生成的xml的文件是没有排版格式,使用普通文本查看器不方便查看、可以使用mxmlSaveFile 中的第三个参数设置成回调函数。代码如下:

#include "config.h"
#include "mxml.h"
#include "mxml-private.h"


const char *whitespace_cb(mxml_node_t *node,int where)
{
    const char *name;
    name = node->value.element.name;   /*获取当前节点的名字*/
    if (!strcmp(name, "data"))         /*判断当前节点的名字是否为data*/
    {
        if (where == MXML_WS_BEFORE_OPEN)  /*如果name == "data",则在节点前加入回车*/
        {
            return ("\n");
        }else if(where == MXML_WS_BEFORE_CLOSE) /*如果name == "data",则在节点前加入回车*/
        {            
            return ("\n");
        }       
    }
    else if (!strcmp(name, "node")) 
    {
        if (where == MXML_WS_BEFORE_OPEN)
        {
            return ("\n\t\t");
        }else if(where == MXML_WS_BEFORE_CLOSE)
        {            
            
        }   
    }else if(!strcmp(name, "group"))
    {
        if (where == MXML_WS_BEFORE_OPEN)
        {
            return ("\n\t\t");
        }else if(where == MXML_WS_BEFORE_CLOSE)
        {            
            return ("\n\t\t");
        }       
    }
    else if (!strcmp(name, "group_node"))
    {
        if (where == MXML_WS_BEFORE_OPEN)
        {
            return ("\n\t\t\t");
        }else if(where == MXML_WS_BEFORE_CLOSE)
        {            
            
        }
    }
    return (NULL);
}

int main()
{
    mxml_node_t *xml;    /*定义根节点指针*/
    mxml_node_t *data;   /*定义节点指针*/
    mxml_node_t *node;   /*定义节点指针*/
    mxml_node_t *group;  /*定义节点指针*/
    xml = mxmlNewXML("1.0");  /*设置xml版本号*/
    data = mxmlNewElement(xml, "data");  /*设置根节点data*/
    mxmlElementSetAttr(data,"type","val");  /*设置节点data的属性为val*/
    node = mxmlNewElement(data, "node"); /*基于根节点data的基础上新建节点node*/
    mxmlNewText(node, 0, "val1");        /*设置当前节点node的文本为val1*/
    node = mxmlNewElement(data, "node"); /*基于根节点data的基础上新建节点node*/
    mxmlNewText(node, 0, "val2");        /*设置当前节点node的文本为val2*/
    node = mxmlNewElement(data, "node"); /*基于根节点data的基础上新建节点node*/
    mxmlNewText(node, 0, "val3");        /*设置当前节点node的文件为val3*/
    group = mxmlNewElement(data, "group"); /*基于根节点data的基础上新建节点group*/
        node = mxmlNewElement(group, "group_node"); /*基于节点group的基础上新建节点group_node*/
        mxmlNewText(node, 0, "val4");               /*设置当前节点group_node的文本为val4*/
        node = mxmlNewElement(group, "group_node"); /*基于节点group的基础上新建节点group_node*/
        mxmlNewText(node, 0, "val5");               /*设置当前节点group_node的文本为val5*/
        node = mxmlNewElement(group, "group_node"); /*基于节点group的基础上新建节点group_node*/
        mxmlNewText(node, 0, "val6");               /*设置当前节点group_node的文本为val6*/
    node = mxmlNewElement(data, "node");            /*基于根节点data的基础上新建节点node*/
    mxmlNewText(node, 0, "val7");                   /*设置当前节点node的文本为val7*/
    node = mxmlNewElement(data, "node");            /*基于根节点data的基础上新建节点node*/
    mxmlNewText(node, 0, "val8");                   /*设置当前节点node的文本为val8*/
    FILE *fp;                                       /*新建文件流指针 fp*/
    fp = fopen("demo.xml","wb");                    /*新建或者打开demo.xml*/
    mxmlSaveFile(xml,fp,whitespace_cb);          /*将数据保存到文件*/
    fclose(fp);                                     /*关闭文件流指针*/
    mxmlDelete(xml);	                            /*关闭xml根节点*/
    return 0;
}

编译后生成文件如下:
Mini-Xml 经典实例Demo_第2张图片

1.2、经典实例Demo_2


<data type="val">
		<node>val1node>
		<node>val2node>
		<node>val3node>
		<group>
			<group_node>val4group_node>
			<group_node>val5group_node>
			<group_node>val6group_node>
		group>
		<node>val7node>
		<node>val8node>
data>

从配置文件中读取数据

#include "config.h"
#include "mxml.h"
#include "mxml-private.h"

int main()
{
    FILE *fp;        /*定义流指针*/
    fp = fopen("demo.xml","r");  /*打开文件demo.xml*/ 
    mxml_node_t  *tree,*data,*group,*node; /*定义节点指针*/
    tree = mxmlLoadFile(NULL,fp,MXML_NO_CALLBACK);  /*获取当前xml的根节点*/
    data = mxmlWalkNext(tree,tree,MXML_DESCEND);    /*从根节点data*/
    data = mxmlWalkNext(data,tree,MXML_NO_DESCEND); /*向下寻找子节点*/
    printf("获取属性:%s\n",mxmlElementGetAttr(data,"type")); /*输出当前节点的属性*/
    node = mxmlWalkNext(data,tree,MXML_DESCEND);      /*data寻找下一级的节点*/
    node = mxmlWalkNext(node,tree,MXML_NO_DESCEND);   /*node寻找同级的节点*/
    printf("获取文本:%s\n",mxmlGetText(node,NULL));

    node = mxmlWalkNext(node,tree,MXML_NO_DESCEND); /*node寻找同级的节点*/
    node = mxmlWalkNext(node,tree,MXML_NO_DESCEND); /*node寻找同级的节点*/
    printf("获取文本:%s\n",mxmlGetText(node,NULL));

    node = mxmlWalkNext(node,tree,MXML_NO_DESCEND); /*node寻找同级的节点*/
    node = mxmlWalkNext(node,tree,MXML_NO_DESCEND); /*node寻找同级的节点*/
    printf("获取文本:%s\n",mxmlGetText(node,NULL)); 

    node = mxmlWalkNext(node,tree,MXML_NO_DESCEND); /*node寻找同级的节点*/
    node = mxmlWalkNext(node,tree,MXML_NO_DESCEND); /*node寻找同级的节点*/

    group = mxmlWalkNext(node,tree,MXML_DESCEND);      /*node寻找下一级的节点*/
    group = mxmlWalkNext(group,tree,MXML_NO_DESCEND);  /*group寻找同级的级节点*/
    printf("获取文本:%s\n",mxmlGetText(group,NULL)); 

    group = mxmlWalkNext(group,tree,MXML_NO_DESCEND); /*group寻找同级的级节点*/
    group = mxmlWalkNext(group,tree,MXML_NO_DESCEND); /*group寻找同级的级节点*/
    printf("获取文本:%s\n",mxmlGetText(group,NULL)); 

    group = mxmlWalkNext(group,tree,MXML_NO_DESCEND); /*group寻找同级的级节点*/
    group = mxmlWalkNext(group,tree,MXML_NO_DESCEND); /*group寻找同级的级节点*/
    printf("获取文本:%s\n",mxmlGetText(group,NULL));


    node  = mxmlWalkNext(node,tree,MXML_NO_DESCEND);  /*node寻找同级的节点*/
    node  = mxmlWalkNext(node,tree,MXML_NO_DESCEND);  /*node寻找同级的节点*/
    printf("获取文本:%s\n",mxmlGetText(node,NULL));

    node  = mxmlWalkNext(node,tree,MXML_NO_DESCEND);  /*node寻找同级的节点*/
    node  = mxmlWalkNext(node,tree,MXML_NO_DESCEND);  /*node寻找同级的节点*/
    printf("获取文本:%s\n",mxmlGetText(node,NULL));     
    return 0;
}

编译后如下:
Mini-Xml 经典实例Demo_第3张图片
代码解析:
1、mxmlLoadFile:载入一个文件到一个XML节点树。

mxml_node_t *mxmlLoadFile ( 
    mxml_node_t *top, 
    FILE *fp, 
    mxml_load_cb_t cb 
);

参数
top :顶级节点
fp:准备读取的文件
cb:回调函数或MXML_NO_CALLBACK
返回值:第一个节点或者NULL代表文件不能被读取。

2、mxmlWalkNext:遍历到XML树中的下一个逻辑节点。

mxml_node_t *mxmlWalkNext ( 
    mxml_node_t *node, 
    mxml_node_t *top, 
    int descend 
);

参数
node:当前节点
top:顶级节点
descend:在XML树中的向下搜索模式 - MXML_DESCEND, MXML_NO_DESCEND, 或者 MXML_DESCEND_FIRST。
返回值:下一个节点或者NULL

3、mxmlElementGetAttr:获取一个参数

const char *mxmlElementGetAttr ( 
    mxml_node_t *node, 
    const char *name 
);

参数
node:XML元素节点
name:属性名称
返回值:属性值或者NULL
4、mxmlGetText:获取元素节点文本

const char *mxmlElementGetAttr ( 
    mxml_node_t *node, 
    NULL 
);

参数
node:XML节点
返回值:文本

1.3、经典实例Demo_3


<Data>
    <animal Dog = "第一只狗" >
        <name>白狗name>
        <nature>暴躁nature>
    animal>       
    <animal Dog = "第二只狗" >
        <name>黄狗name>
        <nature>温顺nature>
     animal>
    <animal Dog = "第三只狗" >
        <name>黑够name> 
        <nature>孤僻nature>
    animal>      
Data>

循环获取数据

#include "stdio.h"
#include "mxml.h"
#include "config.h"
#include "mxml-private.h"
int main()
{
    FILE*  fp = fopen("dog.xml","r");
    mxml_node_t* data = mxmlLoadFile(NULL,fp,MXML_NO_CALLBACK); /*获取当前节点信息*/
    
    mxml_node_t* animal = mxmlFindElement(data,data,"animal",NULL,NULL,MXML_DESCEND); /*寻找animal节点*/
    printf("%s的名字是",mxmlElementGetAttr(animal,"Dog"));
    mxml_node_t* name = mxmlFindElement(data,data,"name",NULL,NULL,MXML_DESCEND);     /*寻找name节点*/
    printf("%s他的性格",mxmlGetText(name,NULL));
    mxml_node_t* nature = mxmlFindElement(data,data,"nature",NULL,NULL,MXML_DESCEND); /*寻找nature节点*/
    printf("%s\n",mxmlGetText(nature,NULL));
    while(1)
    {
        animal = mxmlFindElement(animal,data,"animal",NULL,NULL,MXML_DESCEND);
        if(animal==NULL)
        {
            break;
        }
        printf("%s的名字是",mxmlElementGetAttr(animal,"Dog"));
        name = mxmlFindElement(name,data,"name",NULL,NULL,MXML_DESCEND);
        printf("%s他的性格",mxmlGetText(name,NULL));
        nature = mxmlFindElement(nature,data,"nature",NULL,NULL,MXML_DESCEND);
        printf("%s\n",mxmlGetText(nature,NULL));       
    }

    mxmlDelete(data);
    fclose(fp); 
    return 0;
}

编译运行如下:
Mini-Xml 经典实例Demo_第4张图片


二、总结

Mini-XML是一个小型的Xml解析库,在嵌入式应用程序开发,有着广泛的应用。

你可能感兴趣的:(C语言Mxml常规应用开发,xml,c++,c语言,数据结构,mxml)