C语言学习之路-libxml使用(创建读取修改)

这篇博客介绍了如何使用C语言中的libxml库来创建、读取和修改XML文件。通过示例代码展示了如何添加节点、设置属性以及读取和修改节点内容。最后,博主还提供了一个经过修改后的XML文件示例。

libxml使用

xml文件创建,读取,修改

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <libxml/parser.h>
#include <libxml/tree.h>


#include "print.h"
#include "xmltools.h"

int main(void) {

/**
     * libxml2库调用
     */
    LibXml();

}

/**
 *
①    用xmlReadFile函数读入一个文件,并返回一个文档指针doc。

②    用xmlDocGetRootElement函数得到根节点curNode。

③    此时curNode->xmlChildrenNode就是根节点的首个子节点,该子节点的兄弟节点可用next指针进行轮询。

④    轮询所有子节点,找到所需的节点,用xmlNodeGetContent取出其内容。

⑤    用properties查找含有某个属性的节点,属性列表指针xmlAttrPtr将指向该节点的属性列表。

⑥    取出该节点的属性,用xmlGetProp取出其属性值。

⑦    xmlFreeDoc函数关闭文档指针,并清除本文档中所有节点动态申请的内存。
 */
void LibXml(){

    printf("start %s\n", "NEW  libXml ");
    /**
     * 创建xml
     */
    xmlDocPtr doc = NULL;
    xmlNodePtr root_node = NULL, node1 = NULL;
    xmlNodePtr node2 = NULL,node2_p1 = NULL,node2_p2 = NULL;
    xmlNodePtr node3 = NULL,node3_p1 = NULL,node3_p2 = NULL;

    doc = xmlNewDoc(BAD_CAST "1.0"); // create a new xml document.
    root_node = xmlNewNode(NULL, BAD_CAST "时序文件"); // create a root node.
    /**
     * root根节点
     */
    xmlDocSetRootElement(doc, root_node);
    /**
     * 子节点,不带参数
     */
    xmlNewChild(root_node, NULL, BAD_CAST "时序", BAD_CAST "test 123 这是一个时序文件");
    /**
     *子节点带参数
     */
    node1 = xmlNewChild(root_node, NULL, BAD_CAST "时序",NULL);

    xmlNewProp(node1, BAD_CAST "版本", BAD_CAST "V1.0.0.1");

    /**
     *子节点多项参数
     */

    node2 = xmlNewNode(NULL, BAD_CAST "时序");

    xmlNewProp(node2, BAD_CAST "时序位号", BAD_CAST "001");

    node2_p1 = xmlNewChild(node2, NULL, BAD_CAST "电机", BAD_CAST "采样水平电机");

    xmlNewProp(node2_p1, BAD_CAST "开始时间", BAD_CAST "00.00.01");

    xmlNewProp(node2_p1, BAD_CAST "结束时间", BAD_CAST "00.05.00");

    xmlNewProp(node2_p1, BAD_CAST "方向", BAD_CAST "0");

    xmlNewProp(node2_p1, BAD_CAST "步数", BAD_CAST "500");

    node2_p2 = xmlNewChild(node2, NULL, BAD_CAST "电磁阀", BAD_CAST "1号阀");

    xmlNewProp(node2_p2, BAD_CAST "开始时间", BAD_CAST "00.00.01");

    xmlNewProp(node2_p2, BAD_CAST "结束时间", BAD_CAST "00.03.00");
    /**
     *子节点多项参数2
     */

    node3 = xmlNewNode(NULL, BAD_CAST "时序");

    xmlNewProp(node3, BAD_CAST "时序位号", BAD_CAST "002");

    node3_p1 = xmlNewChild(node3, NULL, BAD_CAST "电机", BAD_CAST "采样纵向电机");

    xmlNewProp(node3_p1, BAD_CAST "开始时间", BAD_CAST "00.01.01");

    xmlNewProp(node3_p1, BAD_CAST "结束时间", BAD_CAST "00.06.00");

    xmlNewProp(node3_p1, BAD_CAST "方向", BAD_CAST "复位");

    xmlNewProp(node3_p1, BAD_CAST "步数", BAD_CAST "666");

    node3_p2 = xmlNewChild(node3, NULL, BAD_CAST "电磁阀", BAD_CAST "9号阀");

    xmlNewProp(node3_p2, BAD_CAST "开始时间", BAD_CAST "00.00.21");

    xmlNewProp(node3_p2, BAD_CAST "结束时间", BAD_CAST "00.03.50");
    /**
     * 插入根节点
     */
    xmlAddChild(root_node, node1);

    xmlAddChild(root_node, node2);

    xmlAddChild(root_node, node3);

    xmlAddChild(node2, node2_p1);

    xmlAddChild(node2, node2_p2);

    xmlAddChild(node3, node3_p1);

    xmlAddChild(node3, node3_p2);


    xmlSaveFormatFileEnc("CreatedXml.xml",doc,"UTF-8",1);

    /**
     * 读取xml
     */
    printf("读取xml ------------------------------------ \n %s");

    xmlNodePtr curNode;

    xmlKeepBlanksDefault(0);
    doc = xmlReadFile("CreatedXml.xml", "UTF-8", XML_PARSE_RECOVER); // open a xml doc.
    curNode = xmlDocGetRootElement(doc); // get root element.

    if (curNode == NULL)
    {
        fprintf(stderr, "open file failed. \n");
        xmlFreeDoc (doc);

    }

    curNode = curNode->children; // root下一层

    char *nodeName;
    char *content;

    while (curNode != NULL)
    {
        nodeName = (char *) curNode->name;
        content = (char *) xmlNodeGetContent(curNode);
        printf ("父节点name  %s,\t content %s\n\n", nodeName, content);

        if(curNode->properties!=NULL){
            xmlAttrPtr attrPtr = curNode->properties;

            while (attrPtr != NULL)
            {
                nodeName = (char *) attrPtr->name;
                content = (char *) xmlGetProp(curNode,attrPtr->name);
                printf ("父节点内容 name %s,\t content %s\n\n", nodeName, content);

                attrPtr = attrPtr->next;
            }

        }


        if(curNode->children!=NULL){
            xmlNodePtr curNode1 = curNode->children;
            nodeName = (char *) curNode1->name;
            content = (char *) xmlNodeGetContent(curNode1);
            printf ("子节点内容 %s,\t %s\n\n", nodeName, content);
            if(curNode1->properties!=NULL){
                xmlAttrPtr attrPtr = curNode1->properties;

                while (attrPtr != NULL)
                {
                    nodeName = (char *) attrPtr->name;
                    content = (char *) xmlGetProp(curNode1,attrPtr->name);
                    printf ("子节点prop  %s,\t  %s\n\n", nodeName, content);

                    attrPtr = attrPtr->next;
                }
            }

        }
        curNode = curNode->next;//依次读取子节点
    }

    /**
     * xml修改
     */
    EditlibXml();

    xmlFree(curNode);

    xmlFreeDoc(doc);

    xmlCleanupParser();

    xmlMemoryDump();
}

void     EditlibXml(){
    xmlNodePtr curNode;
    xmlDocPtr doc = NULL;
    xmlKeepBlanksDefault(0);
    doc = xmlReadFile("CreatedXml.xml", "UTF-8", XML_PARSE_RECOVER); // open a xml doc.
    curNode = xmlDocGetRootElement(doc); // get root element.

    printf("start %s\n", "EditlibXml -----------------------------------");

    curNode = curNode->children; // root下一层

    char *nodeName;
    char *content;

    while (curNode != NULL)
    {
        nodeName = (char *) curNode->name;
        content = (char *) xmlNodeGetContent(curNode);
        printf ("父节点name  %s,\t content %s\n\n", nodeName, content);

        if(curNode->properties!=NULL){
            xmlAttrPtr attrPtr = curNode->properties;

            while (attrPtr != NULL)
            {
                nodeName = (char *) attrPtr->name;
                content = (char *) xmlGetProp(curNode,attrPtr->name);
                printf ("父节点内容 name %s,\t content %s\n\n", nodeName, content);
                if (!xmlStrcmp(content, BAD_CAST "001")) {
                    printf("start %s\n", "get 001 时序 ");

                    curNode = curNode->children; // 下一层
                    nodeName = (char *) curNode->name;
                    content = (char *) xmlNodeGetContent(curNode);
                    printf ("子节点内容 %s,\t %s\n\n", nodeName, content);
                    if(curNode->properties!=NULL){
                        xmlAttrPtr attrPtr = curNode->properties;

                        while (attrPtr != NULL)
                        {
                            nodeName = (char *) attrPtr->name;
                            content = (char *) xmlGetProp(curNode,attrPtr->name);
                            printf ("子节点prop  %s,\t  %s\n\n", nodeName, content);
                            if (!xmlStrcmp(nodeName, BAD_CAST "步数")) {

                                printf ("get参数  %s,\t  %s\n\n", nodeName, content);
                                /**
                                 * 修改
                                 */
                                xmlSetProp(curNode,nodeName,"789");

                                nodeName = (char *) attrPtr->name;
                                content = (char *) xmlGetProp(curNode,attrPtr->name);
                                printf ("set参数  %s,\t  %s\n\n", nodeName, content);
                                /**
                                 * 保存
                                 */

                                //return;
                            }
                            attrPtr = attrPtr->next;
                        }
                    }


                }
                attrPtr = attrPtr->next;
            }

        }
        curNode = curNode->next;//依次读取子节点
    }
    /**
     * 执行完再保存,中途return修改无效
     */
    xmlSaveFormatFileEnc("CreatedXml.xml",doc,"UTF-8",1);
}

输出:

start NEW  libXml
读取xml ------------------------------------
 父节点name  时序,     content test 123 这是一个时序文件

子节点内容 text,     test 123 这是一个时序文件

父节点name  时序,     content

父节点内容 name 版本,     content V1.0.0.1

父节点name  时序,     content 采样水平电机1号阀

父节点内容 name 时序位号,     content 001

子节点内容 电机,     采样水平电机

子节点prop  开始时间,      00.00.01

子节点prop  结束时间,      00.05.00

子节点prop  方向,      0

子节点prop  步数,      500

父节点name  时序,     content 采样纵向电机9号阀

父节点内容 name 时序位号,     content 002

子节点内容 电机,     采样纵向电机

子节点prop  开始时间,      00.01.01

子节点prop  结束时间,      00.06.00

子节点prop  方向,      复位

子节点prop  步数,      666

start EditlibXml -----------------------------------
父节点name  时序,     content test 123 这是一个时序文件

父节点name  时序,     content

父节点内容 name 版本,     content V1.0.0.1

父节点name  时序,     content 采样水平电机1号阀

父节点内容 name 时序位号,     content 001

start get 001 时序
子节点内容 电机,     采样水平电机

子节点prop  开始时间,      00.00.01

子节点prop  结束时间,      00.05.00

子节点prop  方向,      0

子节点prop  步数,      500

get参数  步数,      500

set参数  步数,      789

父节点name  电磁阀,     content 1号阀

父节点内容 name 开始时间,     content 00.00.01

父节点内容 name 结束时间,     content 00.03.00

XML文件:

<时序文件>
  <时序>test 123 这是一个时序文件</时序>
  <时序 版本="V1.0.0.1"/>
  <时序 时序位号="001">
    <电机 开始时间="00.00.01" 结束时间="00.05.00" 方向="0" 步数="789">采样水平电机</电机>
    <电磁阀 开始时间="00.00.01" 结束时间="00.03.00">1号阀</电磁阀>
  </时序>
  <时序 时序位号="002">
    <电机 开始时间="00.01.01" 结束时间="00.06.00" 方向="复位" 步数="666">采样纵向电机</电机>
    <电磁阀 开始时间="00.00.21" 结束时间="00.03.50">9号阀</电磁阀>
  </时序>
</时序文件>

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值