1. 构建xmlDocPtr对象,xmlParseMemory(str,str.len) 字符串转为XML文档 , 从文件读取内容构建xmlReadFile(szDocName,"GB2312",XML_PARSE_RECOVER)
2. xmlDocGetRootElement(),获取XML文档根节点
3. xmlStrcmp,比较XML字符串,与strcmp差不多 ,
4. curr = curr->xmlChildrenNode,XML节点指针指向第一个子节点;curr->properties 节点属性
5. curr = curr->next,XML节点指针指向下一个兄弟节点
6. xmlNodeGetContent,获取XML节点的内容;xmlGetProp获取属性
7. xmlFreeDoc,释放节点,与free差不多
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);
-
- xmlFree(szAttr);
- }
- attrPtr = attrPtr->next;
- }
-
-
- while (itemNodePtr != NULL){
- int frameNum = 0;
- int peopleID = 0;
- Rect rect;
-
-
- 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);
-
- xmlFree(szAttr);
- }
- attrPtr = attrPtr->next;
- }
-
-
- 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;
-
- }
- childNodePtr = childNodePtr->next;
- }
-
- itemNodePtr = itemNodePtr->next;
- }
-
- xmlFreeDoc(doc);
- return filename;
- }
int GetSituation(const std::string&response) const
{
int situation = -1;
if(true)
{
const char* xmlContent = response.c_str();
xmlDocPtr doc;
xmlNodePtr cur;
doc = xmlParseMemory(xmlContent, strlen(xmlContent));
if(doc == NULL) {
LOG(ERROR) << "document not parsed successully.";
return situation;
}
cur = xmlDocGetRootElement(doc);
if(cur == NULL) {
LOG(ERROR) << "document is empty.";
return situation;
}
if(xmlStrcmp(cur->name, (const xmlChar*) "result")) {
LOG(ERROR) << "document of wrong type.";
return situation;
}
cur = cur->xmlChildrenNode;
while(cur != NULL)
{
if(!xmlStrcmp(cur->name, (const xmlChar*) "situation")) {
char* situStr = (char*)xmlNodeGetContent(cur);
LOG(INFO) << "situation is: " << situStr;
situation = atoi(situStr);
xmlFree(situStr);
return situation;
}
cur = cur->next;
}
}
return situation;
}