C语言读写XML文档:libmxml库初学笔记(Mini-XML)

使用XML存取数据很方便。

对应这个需求我选用了libmxml库,官网https://www.msweet.org/mxml/index.html

官网有详尽的英文手册,这里还找到了一份中文手册:

https://blog.csdn.net/bluesonic/article/details/3887143#mxmlEntityGetName

这里只放自己学习时写的测试代码,有兴趣的同学可以做个参考。

#include<mxml.h>

//创建xml文档
    
    //声明创建 xml树需要的 node节点
    mxml_node_t* xml; // xml格式标记
    mxml_node_t* keys_n; // 词汇库,unkey-词汇主键的父节点
    mxml_node_t* unikey_n; //一条词汇记录的基本单元,mark-词汇标签 和 explain-词汇释义 的父节点
    mxml_node_t* elem_n;  //创建 mark explain 的节点
    
    //在内存中通过挂载node节点,构建 xml tree
    xml=mxmlNewXML("1.0");//创建xml文档格式标记,必须,xml tree的根
    keys_n=mxmlNewElement(xml, "keys");//新节点,名为keys,挂载到 xml
    unikey_n=mxmlNewElement(keys_n, "unikey");//新节点,名为unikey,挂载到 keys
    mxmlElementSetAttr(unikey_n, "word", "go alpha");//为unikey_n的节点设置属性:word="go alpha"
    elem_n=mxmlNewElement(unikey_n, "elem");//新节点,名为elem, 挂载到unikey
    mxmlElementSetAttr(elem_n, "element", "mark");//为elem_n的节点设置属性:element="mark"
    mxmlNewText(elem_n, 0, "AI");//为elem_n的节点新增文本,文本前的whitespace(空格)个数为0,内容为”AI”
    elem_n=mxmlNewElement(unikey_n, "elem");//新节点,名为elem, 挂载到unikey
    mxmlElementSetAttr(elem_n, "element", "explain");//为elem_n的节点设置属性:element="explain"
    
    mxmlNewText(elem_n, 0, "Google的AI程序");//为elem_n的节点新增文本,文本前的whitespace(空格)个数为0
    
    //将内存中创建的节点树写入文件
    FILE *fp = fopen("/Users/yaou/Area/tmp/xmltest-1.xml", "w");
    mxmlSaveFile(xml, fp, MXML_NO_CALLBACK);
    
    //关闭文件
    fclose(fp);
    //释放内存中的 节点树
    mxmlDelete(xml);

之后手动在新文件xmltext-1.xml 里添加里一些节点。

//读取xml文件
    //读取xml文件内容到内存 ,挂载到 tree节点
    FILE *fp = fopen("/Users/yaou/Area/tmp/xmltest-1.xml", "r");
    mxml_node_t* tree=mxmlLoadFile(NULL, fp, MXML_TEXT_CALLBACK);
    //载入完毕可关闭文件
    fclose(fp);
    
    //遍历节点
    mxml_node_t* tmp = NULL;
    mxml_node_t* elem_tmp = NULL;
    int i=1;
    for(tmp=mxmlFindElement(tree, tree, "unikey", "word", NULL, MXML_DESCEND);
        tmp!=NULL;
        tmp=mxmlFindElement(tmp, tree, "unikey", "word", NULL, MXML_DESCEND) )
    {
        printf("第%d个unikey节点:\n",i);
        //打印word属性值
        printf("属性word=[%s]\n",mxmlElementGetAttr(tmp,"word"));
        //按 节点名为elem 属性element="mark" 查找子节点
        elem_tmp=mxmlFindElement(tmp, tmp, "elem","element","mark", MXML_DESCEND_FIRST);
        //打印子节点的 文本
        printf("\t子节点 mark文本=[%s]\n",mxmlGetText(elem_tmp, 0));
        
        i++;
    }

    //重置节点文本
    if(i==2){
        mxml_node_t* reset=mxmlFindElement(tree , tree, "elem", "element","explain",MXML_DESCEND);
        mxmlSetText(reset,1, "替换文本");
    }
    
    //将内存中的节点树重新写入另一文件
    FILE *fpo = fopen("/Users/yaou/Area/tmp/xmltest-2.xml", "w");
    mxmlSaveFile(tree, fpo, MXML_NO_CALLBACK);
    
    //关闭文件
    fclose(fpo);
    //释放内存中的 节点树
    mxmlDelete(tree);

PS:小经验

尽量统一 节点名 和 属性名 的命名,用 节点属性值 区分数据的类型 能简化数据的取用。

推荐一个编辑器 Atom

 

posted @ 2019-03-01 22:52  亚欧  阅读(5346)  评论(0编辑  收藏  举报