C语言使用xml2库解析xml文件

xml2库的下载编译:

源码下载地址:Releases · GNOME / libxml2 · GitLab

编译:

./autogen.sh
make

注:编译过程中,可能会依赖一些安装包,根据提示进行安装。

解析完整代码:

#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
 
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>

#define DEFAULT_XML_FILE "test.xml"
#define spc(level) PrintSpace(level)

struct st_version_info
{
	char name[16];
	char version[16];
};


struct st_image_info
{
	char image_name[16];
	char image_partion[16];
	unsigned int image_crc32;
};

struct st_update_info
{
	int image_type;
	struct st_image_info *imageinfo;
};

char project_info[32];
struct st_version_info version_ifno[5];
struct st_update_info soc_update_info;
struct st_update_info mcu_update_info;



//输出缩进用的空格(4个)
void PrintSpace(int level)
{
    for(int counter = 0; counter < level; counter++)
    {
        printf("    ");
    }
}

static int parse_project(xmlNodePtr cur_p, char *project_info)
{
    xmlNodePtr cur;  //xml节点//获取树形结构
    xmlChar *project;
	
    cur = cur_p->xmlChildrenNode;
    while(cur)
    {
    	if(!xmlStrcmp(cur->name, (const xmlChar *)"project"))
    	{
    		project = xmlGetProp(cur, "name");
    		printf("project name:%s\n", project);
    	}
    	cur = cur->next;
    }
	return 0;
}

static int parse_version_list(xmlNodePtr cur_p)
{
    xmlNodePtr cur;  //xml节点//获取树形结构
    xmlChar *name;
    xmlChar *version;
	
    cur = cur_p->xmlChildrenNode;
    while(cur)
    {
    	if(!xmlStrcmp(cur->name, (const xmlChar *)"version"))
    	{
    		name = xmlGetProp(cur, "name");
    		printf("name:%s	", name);
    		version = xmlGetProp(cur, "version");
    		printf("version:%s	\n", version);
    	}
    	cur = cur->next;
    }
	return 0;
}

static int parse_soc(xmlNodePtr cur_p)
{
    xmlNodePtr cur;  //xml节点//获取树形结构
    xmlNodePtr cur_child;  //xml节点//获取树形结构
    xmlChar *type;
    xmlChar *crc32;
    xmlChar *filename;
    xmlChar *partition;
    xmlChar *sha256;
	
    cur = cur_p->xmlChildrenNode;
    
    while(cur)
    {
    	if(!xmlStrcmp(cur->name, (const xmlChar *)"install"))
    	{
    		type = xmlGetProp(cur, "type");
    		printf("type:%s	\n", type);
    	}
    	else if(!xmlStrcmp(cur->name, (const xmlChar *)"FILE_LIST"))
    	{
    		cur_child = cur->xmlChildrenNode;
    		while(cur_child)
    		{
    			if(!xmlStrcmp(cur_child->name, (const xmlChar *)"fileinfo"))
    			{
    				crc32 = xmlGetProp(cur_child, "crc32");
    				printf("crc32:%s  ", crc32);
    				filename = xmlGetProp(cur_child, "filename");
    				printf("filename:%s  ", filename);
    				partition = xmlGetProp(cur_child, "partition");
    				printf("partition:%s  ", partition);
    				sha256 = xmlGetProp(cur_child, "sha256");
    				printf("sha256:%s  \n", sha256);
    			}
    			cur_child = cur_child->next;
    		}
    	}
    	cur = cur->next;
    }
	return 0;
}

static int parse_mcu(xmlNodePtr cur_p)
{
    xmlNodePtr cur;  //xml节点//获取树形结构
    xmlNodePtr cur_child;  //xml节点//获取树形结构
    xmlChar *type;
    xmlChar *crc32;
    xmlChar *filename;
    xmlChar *partition;
    xmlChar *sha256;
	
    cur = cur_p->xmlChildrenNode;
    
    while(cur)
    {
    	if(!xmlStrcmp(cur->name, (const xmlChar *)"install"))
    	{
    		type = xmlGetProp(cur, "type");
    		printf("type:%s	\n", type);
    	}
    	else if(!xmlStrcmp(cur->name, (const xmlChar *)"FILE_LIST"))
    	{
    		cur_child = cur->xmlChildrenNode;
    		while(cur_child)
    		{
    			if(!xmlStrcmp(cur_child->name, (const xmlChar *)"fileinfo"))
    			{
    				crc32 = xmlGetProp(cur_child, "crc32");
    				printf("crc32:%s  ", crc32);
    				filename = xmlGetProp(cur_child, "filename");
    				printf("filename:%s  ", filename);
    				partition = xmlGetProp(cur_child, "partition");
    				printf("partition:%s  ", partition);
    				sha256 = xmlGetProp(cur_child, "sha256");
    				printf("sha256:%s  \n", sha256);
    			}
    			cur_child = cur_child->next;
    		}
    	}
    	cur = cur->next;
    }
	return 0;
}

static int parse_xml(const char *file_name)
{	
    assert(file_name);
    
    xmlDocPtr doc;   //xml整个文档的树形结构
    xmlNodePtr cur;  //xml节点//获取树形结构
    
    doc = xmlParseFile(file_name);
    if (doc == NULL) 
    {
		fprintf(stderr, "Failed to parse xml file:%s\n", file_name);
		return -1;
    }
    
    //获取根节点
    cur = xmlDocGetRootElement(doc);
    if (cur == NULL) 
    {
		fprintf(stderr, "Root is empty.\n");
		return -1;
    }
    
    if ((xmlStrcmp(cur->name, (const xmlChar *)"update"))) 
    {
		fprintf(stderr, "The root is not update.\n");
		return -1;
    }
    
    printf("cur->name:%s \n", cur->name);
    
    //遍历处理根节点的每一个子节点
    cur = cur->xmlChildrenNode;
    

    while(cur)
    {
    	if(!xmlStrcmp(cur->name, (const xmlChar *)"project"))
    	{
    		parse_project(cur, project_info);
    	}
    	else if(!xmlStrcmp(cur->name, (const xmlChar *)"version_list"))
    	{
    		parse_version_list(cur);
    	}
    	else if(!xmlStrcmp(cur->name, (const xmlChar *)"v9156_ms_emmc"))
    	{
    		parse_soc(cur);
    	}
    	else if(!xmlStrcmp(cur->name, (const xmlChar *)"v9156_ms_ospi"))
    	{
    		parse_mcu(cur);
    	}
    
    	cur = cur->next;
    }
    
	
	return 0;
}

int main(int argc, char*argv[])
{
	int fd = 0;
	char *buff = "04df9308";
	struct stat filestat;
	unsigned int value = 0;
	sscanf(buff, "%x", &value);
	printf("value=%.8x\n", value);
    char *xml_file = DEFAULT_XML_FILE;
 
    if (argc == 2) 
	{
    	xml_file = argv[1];
    }
    
    if(stat(xml_file, &filestat) < 0)
    {
    	printf("stat %s fail.\n", xml_file);
    	return -1;    
    }
#if 0    
    fd = open(xml_file, O_RDWR);
    if(fd < 0)
    {
    	printf("open %s fail.\n", xml_file);
    	return -1;
    }
    
    ftruncate(xml_file, filestat.st_size-1024);
    close(fd);
    sync();
#else
//	truncate(xml_file, filestat.st_size-1024);
//    sync();
#endif 
    if (parse_xml(xml_file) != 0) 
    {
		fprintf(stderr, "Failed to parse phone book.\n");
		return -1;
    }
 
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

monkey_llll

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值