【C++】使用libxml解析XML文件

OpenCV中使用FileStorage创建和解析XML文件。但FileStorage不能处理节点为空的情况,且对属性也不友好。例子见这里

libxml是C接口的处理xml文件的开源代码库。可以在这里下载。

对于一段如下的xml文件:

<?xml version="1.0"?>
<Message Version="1.0">
  <Info evaluateType="2" mediaFile="1.avi">1</Info>
  <Items>
    <Item frameNum="0" scale="2" />
    <Item frameNum="1" scale="2" />
    <Item frameNum="2" scale="2" />
	<Item frameNum="2913" scale="2">
      <Label type="2" l="564" t="178" r="594" b="280" id="15" />
      <Label type="2" l="528" t="184" r="560" b="288" id="11" />
      <Label type="2" l="490" t="182" r="522" b="288" id="16" />
      <Label type="2" l="614" t="358" r="704" b="600" id="4" />
    </Item>
  </Items>
</Message>
  

libxml处理的函数如下:

string getLabes(char *szDocName, map<pair<int,int>,Rect > &labels){
	xmlDocPtr doc;          
	xmlNodePtr curNode;      
	xmlChar *szKey;          
	string filename="";

	doc = xmlReadFile(szDocName,"GB2312",XML_PARSE_RECOVER); //解析文件

	if (doc==NULL){  
		fprintf(stderr,"Document not parsed successfully.\n");     
		return filename; 

	} 

	curNode = xmlDocGetRootElement(doc); //确定文档根元素
	if (NULL == curNode){ 
		fprintf(stderr,"empty document\n");
		xmlFreeDoc(doc); 
		return filename; 
	} 

	if (xmlStrcmp(curNode->name, BAD_CAST "Message")) {
		fprintf(stderr,"document of the wrong type, root node != Message"); 
		xmlFreeDoc(doc);
		return filename; 
	} 

	curNode = curNode->xmlChildrenNode;
	xmlNodePtr propNodePtr = curNode;
	xmlNodePtr itemNodePtr;  

	while(curNode != NULL){
		//取出文件名称
		if (xmlHasProp(curNode,BAD_CAST "mediaFile")) {
			propNodePtr = curNode;

		} 
		if (!xmlStrcmp(curNode->name, BAD_CAST "Items")) {
			itemNodePtr = curNode->xmlChildrenNode;
		} 
		curNode = curNode->next;
	}

	xmlAttrPtr attrPtr = propNodePtr->properties;
	while (attrPtr != NULL){
		if (!xmlStrcmp(attrPtr->name, BAD_CAST "mediaFile")){
			xmlChar* szAttr = xmlGetProp(propNodePtr,BAD_CAST "mediaFile");
			char* szAttrG = u2g((char*)szAttr);
			filename = string(szAttrG);
			//cout<<"get filename: "<<filename<<endl;
			xmlFree(szAttr);
		}
		attrPtr = attrPtr->next;
	}

	// Item
	while (itemNodePtr != NULL){
		int frameNum = 0;
		int peopleID = 0;
		Rect rect;

		//<Label type="2" l="620" t="164" r="648" b="234" id="15" />
		xmlAttrPtr attrPtr = itemNodePtr->properties;
		while (attrPtr != NULL){
			if (!xmlStrcmp(attrPtr->name, BAD_CAST "frameNum")){
				xmlChar* szAttr = xmlGetProp(itemNodePtr,BAD_CAST "frameNum");
				frameNum = atoi((char*)szAttr);
				//cout<<"get frameNum: "<<frameNum<<endl;
				xmlFree(szAttr);
			}
			attrPtr = attrPtr->next;
		}

		// Label
		xmlNodePtr childNodePtr = itemNodePtr->xmlChildrenNode;
		while (childNodePtr != NULL){
			int l=0,t=0,r=0,b=0;
			attrPtr = childNodePtr->properties; 
			while(attrPtr != NULL){
				if (!xmlStrcmp(attrPtr->name, BAD_CAST "l")){
					xmlChar* szAttr = xmlGetProp(childNodePtr,BAD_CAST "l");
					l=atoi((char*)szAttr);
					xmlFree(szAttr);
				}
				if (!xmlStrcmp(attrPtr->name, BAD_CAST "t")){
					xmlChar* szAttr = xmlGetProp(childNodePtr,BAD_CAST "t");
					t=atoi((char*)szAttr);
					xmlFree(szAttr);
				}
				if (!xmlStrcmp(attrPtr->name, BAD_CAST "r")){
					xmlChar* szAttr = xmlGetProp(childNodePtr,BAD_CAST "r");
					r=atoi((char*)szAttr);
					xmlFree(szAttr);
				}
				if (!xmlStrcmp(attrPtr->name, BAD_CAST "b")){
					xmlChar* szAttr = xmlGetProp(childNodePtr,BAD_CAST "b");
					b=atoi((char*)szAttr);
					xmlFree(szAttr);
				}
				if (!xmlStrcmp(attrPtr->name, BAD_CAST "id")){
					xmlChar* szAttr = xmlGetProp(childNodePtr,BAD_CAST "id");
					peopleID=atoi((char*)szAttr);
					xmlFree(szAttr);
				}
				attrPtr = attrPtr->next;
			}
			if(!(l==0&&t==0&&b==0&&r==0)){
				rect.x=l;rect.y=t;rect.width=r-l;rect.height=b-t;
				labels[pair<int,int>(frameNum,peopleID)] = rect;
				//cout<<"get label: "<<l<<" "<<t<<" "<<r<<" "<<b<<" "<<" "<<peopleID<<endl;
			}
			childNodePtr = childNodePtr->next;
		}

		itemNodePtr = itemNodePtr->next;
	}

	xmlFreeDoc(doc);
	return filename;
}

用map的iterator输出:

for(map<pair<int,int>,Rect >::iterator it=labels.begin();
		it!=labels.end();it++){
			cout<<(*it).first.first<<" "<<(*it).first.second<<" "
				<<(*it).second.x<<" "<<(*it).second.y<<" "
				<<(*it).second.width<<" "<<(*it).second.height<<endl;
	}


(转载请注明作者和出处:http://blog.csdn.net/xiaowei_cqu未经允许请勿用于商业用途)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值