xml数据结构:
xmlChar:对char的基本代替,是一个UTF-8编码字符串中的一个字节
xmlDoc 和 xmlDocPtr: 树的结构
xmlNode 和 xmlNodePtr:单个节点的结构
生成xmldoc、获得根节点,获得子节点
- //4. 解析xml字符串
- xmlDocPtr doc = xmlParseMemory(pXml, length);
- //根据xmldoc获得xml的根节点
- xmlNodePtr cur = xmlDocGetRootElement(doc);
- //获得子节点:->children获得不是第一个子节点,必须用next才能获得第一个子节点
- cur = cur->children;
- cur = cur->next;
- // 获得节点信息中的内容: 注意释放资源
- xmlChar* key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
- xmlFree(key);
- //获得节点信息属性的值:属性name,注意释放资源
- xmlChar* fversion = xmlGetProp(cur, "version");
- xmlFree(fversion);
- //根节点相关函数
- xmlNodePtr xmlDocGetRootElement (xmlDocPtr doc) //获取文档根节点
- xmlNodePtr xmlDocSetRootElement (xmlDocPtr doc, xmlNodePtr root) //设置文档根节点
- //创建子节点相关函数
- xmlNodePtr xmlNewNode (xmlNsPtr ns, const xmlChar * name) //创建新节点
- xmlNodePtr xmlNewChild (xmlNodePtr parent, xmlNsPtr ns, const xmlChar * name, const xmlChar * content) //创建新的子节点
- xmlNodePtr xmlCopyNode (const xmlNodePtr node, int extended) //复制当前节点
- //添加子节点相关函数
- xmlNodePtr xmlAddChild (xmlNodePtr parent, xmlNodePtr cur) //给指定节点添加子节点
- xmlNodePtr xmlAddNextSibling (xmlNodePtr cur, xmlNodePtr elem) //添加后一个兄弟节点
- xmlNodePtr xmlAddPrevSibling (xmlNodePtr cur, xmlNodePtr elem) //添加前一个兄弟节点
- xmlNodePtr xmlAddSibling (xmlNodePtr cur, xmlNodePtr elem) //添加兄弟节点
- //属性相关函数
- xmlAttrPtr xmlNewProp (xmlNodePtr node, const xmlChar * name, const xmlChar * value) //创建新节点属性
- xmlChar * xmlGetProp (xmlNodePtr node, const xmlChar * name) //读取节点属性
- xmlAttrPtr xmlSetProp (xmlNodePtr node, const xmlChar * name, const xmlChar * value) //设置节点属性
- =xmlNodeListGetstring(doc, cur->xmlChildrenNode, 1);
- =xmlNodeContent(cur);
对一个xmldoc解析解析
- void CCommunicationThread::parseXml_doc(xmlDocPtr doc, xmlNodePtr cur, const char* path)
- {
- //1.进入xml的目录时:判断该目录是否存在?否则创建
- cur = cur->children;
- if (cur == NULL)
- return;
- cur = cur->next;
- if (cur == NULL)
- return;
- check_and_create_path(path);
- SVN_MAP file_map;
- char* pMapBuffer = this->get_fileInfor_list(path, file_map);
- //2.将服务器的新版、新增文件信息,压入准备下载的队列,启动线程开始下载.
- xmlChar* fileName;
- xmlChar* fileVersion;
- SVN_MAP map_new;
- while ( cur != NULL)
- {
- if (strcmp((char*)cur->name, "folder") == 0)
- {
- string curPath = path;
- fileName = xmlGetProp(cur, (const xmlChar *)"name");
- curPath = curPath + "\\" + (char*)fileName;
- parseXml_doc(doc, cur, curPath.c_str());
- }
- else if (strcmp((char*)cur->name, "file") == 0)
- {
- // 判断一个文件是否存在?文件是否修改?文件版本号是否与当前的版本号相同?
- fileName = xmlGetProp(cur, (const xmlChar *)"name");
- fileVersion = xmlGetProp(cur, (const xmlChar *)"version");
- FILE_SVN_INFOR* svn_infor = new FILE_SVN_INFOR;
- strcpy(svn_infor->filename, (const char*)fileName);
- svn_infor->version = 0;
- SVN_MAP::iterator it = file_map.find((char*)fileName);
- if (it != file_map.end())
- {
- // 找到该信息,查看版本号
- if (atoi((const char*)fileVersion) > it->second->version)//新版本
- {
- File_Infor* infor = new File_Infor();
- strcpy(infor->command, CMD_DOWNLOAD);
- strcpy(infor->param.download.fileName, (const char*)fileName);
- this->push_list(infor);
- }
- svn_infor->md5 = it->second->md5;
- }
- else
- {
- // 新增
- File_Infor* infor = new File_Infor();
- strcpy(infor->command, CMD_DOWNLOAD);
- strcpy(infor->param.download.fileName, (const char*)fileName);
- this->push_list(infor);
- memset(&svn_infor->md5, 0, sizeof(MD5));
- }
- // 组织新的.svn文件
- map_new[svn_infor->filename] = svn_infor;
- xmlFree(fileName);
- xmlFree(fileVersion);
- }
- cur = cur->next;
- }
- //3.在退出xml目录时:根据文件新的版本存储.svn文件
- free(pMapBuffer);
- set_fileInfor_list(path, map_new);
- for ( SVN_MAP::iterator it = map_new.begin(); it != map_new.end(); it++ )
- {
- delete it->second;
- }
- map_new.clear();
- return;
- }