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>
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; }
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; }