最近在封裝一個sdk接口給內部使用的時候,原來項目都是用c++開發的,xml解析工具用的是:Tinyxml,挺不錯,至少不用考慮內存釋放問題。這也是c++資源管理的好處。。。
因爲提供的是c的接口,所以tinyxml顯然不能用了。後面就想到用libxml2,因爲他用C語言開發的。網上想找現成的,結果發現都是解析文件的,記錄一下解析xml字符串的過程吧,主要是內存的管理小心一點就OK了:
xmlNodePtr GetNextXmlNode(xmlNodePtr pstXmlNode)
{
pstXmlNode = pstXmlNode->next;
while(pstXmlNode)
{
if (XML_ELEMENT_NODE == pstXmlNode->type)
{
return pstXmlNode;
}
pstXmlNode = pstXmlNode->next;
}
}
xmlNodePtr GetChildrenXmlNode(xmlNodePtr pstXmlNode)
{
pstXmlNode = pstXmlNode->children;
while(pstXmlNode)
{
if (XML_ELEMENT_NODE == pstXmlNode->type)
{
return pstXmlNode;
}
pstXmlNode = pstXmlNode->next;
}
}
static int ParseAppReqMsg(char *pszPayload , APP_RES_INFO *pstResInfo)
{
if ((NULL == pstAppResInfo) || (NULL == pszRecvMsg))
{
return -1;
}
int nXmlSize = 0;
nXmlSize = strlen(pszPayload);
xmlDocPtr pstXmlDoc = NULL;
xmlNodePtr pstXmlNode = NULL;
xmlNodePtr pstXmlSubNode = NULL;
char *pszXmlNodeContent = NULL;
pstXmlDoc = xmlParseMemory(pszPayload, nXmlSize);
if (!pstXmlDoc)
{
printf("%s_%d: xmlParseMemory failed ,the xml is: %s", _LOG_TRACE_, pszPayload);
return -1;
}
pstXmlNode = xmlDocGetRootElement(pstXmlDoc);
if(!pstXmlNode)
{
xmlFreeDoc(pstXmlDoc);
printf("%s_%d: xmlDocGetRootElement failed .", _LOG_TRACE_);
return -1;
}
pstXmlSubNode = GetChildrenXmlNode(pstXmlNode);
while(NULL != pstXmlSubNode)
{
pszXmlNodeContent = (char *)xmlNodeGetContent(pstXmlSubNode);
if (0 == xmlStrncmp(pstXmlSubNode->name,XML_NODE_NAME_MSG_TYPE,sizeof(XML_NODE_NAME_MSG_TYPE)))
{
//to do 判斷是否爲:UpdateDevConf,目前暫不處理
}
else if (0 == xmlStrncmp(pstXmlSubNode->name,XML_NODE_NAME_MSG_PROTOCAL,sizeof(XML_NODE_NAME_MSG_PROTOCAL)))
{
//to do 判斷是否爲:1.0版本,目前暫不處理
}
else if (0 == xmlStrncmp(pstXmlSubNode->name,XML_NODE_NAME_MSG_PARAM,sizeof(XML_NODE_NAME_MSG_PARAM)))
{
char *pszXmlParamsContent = NULL;
xmlNodePtr pstXmlSubParamsNode = NULL;
pstXmlSubParamsNode = GetChildrenXmlNode(pstXmlSubNode);
while(NULL != pstXmlSubParamsNode)
{
pszXmlParamsContent = (char *)xmlNodeGetContent(pstXmlSubParamsNode);
if (0 == xmlStrncmp(pstXmlSubNode->name,XML_NODE_NAME_MSG_PARAM_APP_NO,sizeof(XML_NODE_NAME_MSG_PARAM_APP_NO)))
{
strncpy(pstResInfo->szAppNo, pszXmlParamsContent, APP_NO_SIZE -1);
pstResInfo->szAppNo[APP_NO_SIZE -1] = 0;
}
else if (0 == xmlStrncmp(pstXmlSubNode->name,XML_NODE_NAME_MSG_PARAM_CONFIGURL,sizeof(XML_NODE_NAME_MSG_PARAM_CONFIGURL)))
{
strncpy(pstResInfo->szConfigUrl, pszXmlParamsContent, URL_SIZE -1);
pstResInfo->szAppNo[URL_SIZE -1] = 0;
}
else if (0 == xmlStrncmp(pstXmlSubNode->name,XML_NODE_NAME_MSG_PARAM_CONFIGMD5,sizeof(XML_NODE_NAME_MSG_PARAM_CONFIGMD5)))
{
strncpy(pstResInfo->szConfigMd5, pszXmlParamsContent, MD5_SIZE -1);
pstResInfo->szAppNo[MD5_SIZE -1] = 0;
}
xmlFree(pszXmlParamsContent);
pszXmlParamsContent = NULL;
pstXmlSubParamsNode = GetNextXmlNode(pstXmlSubParamsNode);
}
}
xmlFree(pszXmlNodeContent);
pszXmlNodeContent= NULL;
pstXmlSubNode = GetNextXmlNode(pstXmlSubNode);
}
xmlFreeDoc(pstXmlDoc);
return 0;
}