xml标记文件中的数据 读取出来【测试通过】

借助libxml2库进行xml文件的读写,本篇记录读取文件
【libxml2算法库、头文件在这里下载】
这里需要处理的xml文件格式如下所示。其中,包含了“根节点”、“子节点”、“子节点属性(孙子节点)”;如有更深刻进一步修改复用。

<?xml version="1.0" encoding="utf-8"?>
<annotation>
	<filename>5d648b8073497c9e9490b50bdc175a7_1003959936.jpg</filename>
	<size>
		<width>1920</width>
		<height>1088</height>
		<depth>3</depth>
	</size>
	<object>
		<name>0</name>
		<truncated>0</truncated>
		<bndbox>
			<xmin>832</xmin>
			<ymin>336</ymin>
			<xmax>1853</xmax>
			<ymax>1008</ymax>
		</bndbox>
	</object>
	<object>
		<name>0</name>
		<truncated>0</truncated>
		<bndbox>
			<xmin>111</xmin>
			<ymin>222</ymin>
			<xmax>333</xmax>
			<ymax>444</ymax>
		</bndbox>
	</object>
</annotation>


通过以下代码,将xml文件中的所有数据读取出来


#include<libxml/parser.h>
#include<libxml/tree.h>
//定义size节点结构体
typedef struct size_node{
	int width;
	int height;
	int depth;
}size_node;
//定义object节点结构体
typedef struct object_node{
	int name;
	int truncated;
	int xmin;
	int ymin;
	int xmax;
	int ymax;
}object_node;
//定义xml文件所有数据结构体
typedef struct xml_data{
	string filename;
	size_node size;
	object_node objects[20];
	int node_nums;
}xml_data;
/*function:将xml文件数据读取到xml_data类型的变量中*/
int parse_xml_struct_Data(string xml_path, xml_data* xml_info)
{
	xmlDocPtr doc;           //定义解析文档指针
	xmlNodePtr curNode;      //定义结点指针(你需要它为了在各个结点间移动)
	xmlNodePtr curNode_chile;
	xmlNodePtr curNode_chile_child;
	//xmlChar* attr_value = NULL;
	xmlChar *szKey;          //临时字符串变量
	char szDocName[500];
	strcpy(szDocName, xml_path.c_str());
	using std::string;
	using std::cout;
	using std::endl;

	doc = xmlReadFile(szDocName, "UTF-8", XML_PARSE_RECOVER); //解析文件
	if (NULL == doc)
	{
		//文档打开错误
		return -1;
	}
	curNode = xmlDocGetRootElement(doc); //确定文档根元素
	/*检查确认当前文档中包含内容*/
	if (NULL == curNode)
	{
		//空得xml文件
		xmlFreeDoc(doc);
		return -2;
	}
	/*在这个例子中,我们需要确认文档是正确的类型。“annotation”是在这个示例中使用文档的根类型。*/
	if (xmlStrcmp(curNode->name, BAD_CAST "annotation"))
	{
		//分析根元素失败
		xmlFreeDoc(doc);
		return -3;
	}

	curNode = curNode->xmlChildrenNode;
	xmlNodePtr propNodePtr = curNode;
	while (curNode != NULL)
	{
		//取出节点中的内容
		if (xmlStrcmp(curNode->name, (const xmlChar *)"text") == 0)
		{
			curNode = curNode->next;
			if (curNode == NULL)
			{
				break;
			}
		}
		if (xmlStrcmp(curNode->name, (const xmlChar *)"filename") == 0)
		{
			szKey = xmlNodeGetContent(curNode);
			//cout << szKey << endl; //得到node2的值并输出
			char files[500];
			sprintf(files, "%s", szKey);
			xml_info->filename = string(files);
			xmlFree(szKey);
		}
		else if (xmlStrcmp(curNode->name, (const xmlChar *)"size") == 0)
		{
			szKey = xmlNodeGetContent(curNode);
			//cout << szKey << endl; //得到node2的值并输出
			xmlFree(szKey);

			curNode_chile = curNode->xmlChildrenNode;

			//子节点的子节点没有遍历结束,就继续遍历
			while (curNode_chile->next != NULL)
			{
				while (xmlStrcmp(curNode_chile->name, (const xmlChar *)"text") == 0)
				{
					curNode_chile = curNode_chile->next;
				}
				if (xmlStrcmp(curNode_chile->name, (const xmlChar *)"width") == 0)
				{
					szKey = xmlNodeGetContent(curNode_chile);
					char * stream = (char*)szKey;
					//cout << "width = " << szKey << endl; //得到node2的值并输出
					xml_info->size.width = atoi(stream);
					xmlFree(szKey);
				}
				if (xmlStrcmp(curNode_chile->name, (const xmlChar *)"height") == 0)
				{
					szKey = xmlNodeGetContent(curNode_chile);
					//cout << "height = " << szKey << endl; //得到node2的值并输出
					char * stream = (char*)szKey;
					xml_info->size.height = atoi(stream);
					xmlFree(szKey);

				}
				if (xmlStrcmp(curNode_chile->name, (const xmlChar *)"depth") == 0)
				{
					szKey = xmlNodeGetContent(curNode_chile);
					//cout << "depth = " << szKey << endl; //得到node2的值并输出
					char * stream = (char*)szKey;
					xml_info->size.depth = atoi(stream);
					xmlFree(szKey);
				}
				curNode_chile = curNode_chile->next;
			}
		}
		else if (xmlStrcmp(curNode->name, (const xmlChar *)"object") == 0)
		{
			//szKey = xmlNodeGetContent(curNode);
			//cout << szKey << endl; //得到node2的值并输出
			//xmlFree(szKey);
			object_node* obj_tmp = &(xml_info->objects[xml_info->node_nums]);
			curNode_chile = curNode->xmlChildrenNode;

			while (curNode_chile->next != NULL)
			{
				while (xmlStrcmp(curNode_chile->name, (const xmlChar *)"text") == 0)
				{
					curNode_chile = curNode_chile->next;
				}
				if (xmlStrcmp(curNode_chile->name, (const xmlChar *)"name") == 0)
				{
					szKey = xmlNodeGetContent(curNode_chile);
					//cout << "name = " << szKey << endl; //得到node2的值并输出
					char * stream = (char*)szKey;
					obj_tmp->name = atoi(stream);
					xmlFree(szKey);
				}
				if (xmlStrcmp(curNode_chile->name, (const xmlChar *)"truncated") == 0)
				{
					szKey = xmlNodeGetContent(curNode_chile);
					//cout << "truncated = " << szKey << endl; //得到node2的值并输出
					char * stream = (char*)szKey;
					obj_tmp->truncated = atoi(stream);
					xmlFree(szKey);
				}
				if (xmlStrcmp(curNode_chile->name, (const xmlChar *)"bndbox") == 0)
				{
					//szKey = xmlNodeGetContent(curNode_chile);
					//cout << "bndbox = " << szKey << endl; //得到node2的值并输出
					//xmlFree(szKey);
					curNode_chile_child = curNode_chile->xmlChildrenNode;
					while (curNode_chile_child->next != NULL)
					{
						while (xmlStrcmp(curNode_chile_child->name, (const xmlChar *)"text") == 0)
						{
							curNode_chile_child = curNode_chile_child->next;
						}
						if (xmlStrcmp(curNode_chile_child->name, (const xmlChar *)"xmin") == 0)
						{
							szKey = xmlNodeGetContent(curNode_chile_child);
							//cout << "xmin = " << szKey << endl; //得到node2的值并输出
							char * stream = (char*)szKey;
							obj_tmp->xmin = atoi(stream);
							xmlFree(szKey);
						}
						if (xmlStrcmp(curNode_chile_child->name, (const xmlChar *)"ymin") == 0)
						{
							szKey = xmlNodeGetContent(curNode_chile_child);
							//cout << "ymin = " << szKey << endl; //得到node2的值并输出
							char * stream = (char*)szKey;
							obj_tmp->ymin = atoi(stream);
							xmlFree(szKey);
						}
						if (xmlStrcmp(curNode_chile_child->name, (const xmlChar *)"xmax") == 0)
						{
							szKey = xmlNodeGetContent(curNode_chile_child);
							//cout << "xmax = " << szKey << endl; //得到node2的值并输出
							char * stream = (char*)szKey;
							obj_tmp->xmax = atoi(stream);
							xmlFree(szKey);
						}
						if (xmlStrcmp(curNode_chile_child->name, (const xmlChar *)"ymax") == 0)
						{
							szKey = xmlNodeGetContent(curNode_chile_child);
							//cout << "ymax = " << szKey << endl; //得到node2的值并输出
							//cout << "xmax = " << szKey << endl; //得到node2的值并输出
							char * stream = (char*)szKey;
							obj_tmp->ymax = atoi(stream);
							xmlFree(szKey);
						}
						curNode_chile_child = curNode_chile_child->next;
					}
				}
				curNode_chile = curNode_chile->next;
			}
			xml_info->node_nums++;

		}

		curNode = curNode->next;
	}
	if (xml_info->node_nums <1)
	{
		xmlFreeDoc(doc);
		return -4;
	}
	xmlFreeDoc(doc);
	return 0;
}
int main(int argc, char *argv[])
{
	string xml_path = "D:\\1003959936.xml"; 
	xml_data* xml_info = (xml_data*)malloc(sizeof(xml_data));
	memset(xml_info, 0, sizeof(xml_data));
	parse_xml_struct_Data(xml_path, xml_info);
	free(xml_info )
}

结果为:
在这里插入图片描述

-------------------------------------------分割线---------------------------------------------------
将yolo检测到的目标,保存到xml文件中。核心函数记录:

//imgFullName 图片的名字,不带后缀
int write_xml_1(int imgW, int imgH, int channels, detection *dets, int num, float thresh, char *imgFullName, char* saveFolder) //filename:: xml文件名 node::写入的节点名 data:写入的节点数据
{
	int selected_detections_num;
	int i;

	char xminStr[10];	char yminStr[10];	
	char xmaxStr[10];	char ymaxStr[10];
	char imgWidth[10];	char imgHeight[10];
	char imgChannel[10];

	char filename[500];

	int preNameLen = strlen(imgFullName);
	memset(filename, 0, 500);
	memcpy(filename, imgFullName, preNameLen - 4);

	sprintf(filename, "%s.xml", filename);
	//selected_detections 从*dets中得到置信度大于thresh(0.25)的元素,并且计算得到了最佳类别和最佳置信度
	detection_with_class* selected_detections = get_actual_detections(dets, num, thresh, &selected_detections_num);

	xmlDocPtr doc;
	doc = xmlReadFile(filename, "UTF-8", XML_PARSE_NOBLANKS);
	if (doc == NULL) //文件不存在 创建一个新文件
	{
		char* imagenameTmp = NULL;
		imagenameTmp = G2U(imgFullName);
		xmlDocPtr doc = xmlNewDoc(BAD_CAST"1.0");
		xmlNodePtr root_node = xmlNewNode(NULL, BAD_CAST"annotation");
		xmlNodePtr filename_node = xmlNewTextChild(root_node, NULL, BAD_CAST "filename", BAD_CAST imagenameTmp);
		free(imagenameTmp);

		//xmlNewTextChild(root_node, NULL, BAD_CAST "size", BAD_CAST data);
		//设置根节点
		xmlDocSetRootElement(doc, root_node);

		xmlNodePtr size_node = xmlNewNode(NULL, BAD_CAST"size");
		xmlAddSibling(filename_node, size_node);

		xmlNewTextChild(size_node, NULL, BAD_CAST "width", BAD_CAST _itoa(imgW, imgWidth, 10));
		xmlNewTextChild(size_node, NULL, BAD_CAST "height", BAD_CAST _itoa(imgH, imgHeight, 10));
		xmlNewTextChild(size_node, NULL, BAD_CAST "depth", BAD_CAST _itoa(channels, imgChannel, 10));

		bool saveXMLflag = false;
		for (i = 0; i < selected_detections_num; ++i)
		{
			int name = selected_detections[i].best_class;

			if (name!=0)
			{
				continue;
			}
			saveXMLflag = true;
			box b = selected_detections[i].det.bbox;
			//printf("%f %f %f %f\n", b.x, b.y, b.w, b.h);

			int left = (b.x - b.w / 2.)*imgW;
			int right = (b.x + b.w / 2.)*imgW;
			int top = (b.y - b.h / 2.)*imgH;
			int bot = (b.y + b.h / 2.)*imgH;

			if (left < 0) left = 0;
			if (right > imgW - 1) right = imgW - 1;
			if (top < 0) top = 0;
			if (bot > imgH - 1) bot = imgH - 1;

			xmlNodePtr object_node = xmlNewNode(NULL, BAD_CAST"object");
			xmlAddSibling(filename_node, object_node);

			xmlNodePtr name_node = xmlNewTextChild(object_node, NULL, BAD_CAST "name", BAD_CAST "1");
			//bndbox
			xmlNodePtr bndbox_node = xmlNewNode(NULL, BAD_CAST"bndbox");
			xmlAddSibling(name_node, bndbox_node);

			xmlNewTextChild(bndbox_node, NULL, BAD_CAST "xmin", BAD_CAST _itoa(left, xminStr, 10));
			xmlNewTextChild(bndbox_node, NULL, BAD_CAST "ymin", BAD_CAST _itoa(top, yminStr, 10));
			xmlNewTextChild(bndbox_node, NULL, BAD_CAST "xmax", BAD_CAST _itoa(right, xmaxStr, 10));
			xmlNewTextChild(bndbox_node, NULL, BAD_CAST "ymax", BAD_CAST _itoa(bot, ymaxStr, 10));
		}
		if (!saveXMLflag)
		{
			xmlFreeDoc(doc);
			return 0;
		}
		sprintf(saveFolder, "%s%s", saveFolder, filename);
		xmlSaveFormatFileEnc(saveFolder, doc, "UTF-8", 1); 
		xmlFreeDoc(doc);
		return 0;
	}
	xmlNodePtr cur;
	cur = xmlDocGetRootElement(doc);
	if (cur == NULL)
	{
		xmlFreeDoc(doc);
		return -1;
	}
	xmlFreeDoc(doc);
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值