惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
Engineering at Meta
Engineering at Meta
D
DataBreaches.Net
月光博客
月光博客
Recent Announcements
Recent Announcements
Google DeepMind News
Google DeepMind News
U
Unit 42
腾讯CDC
爱范儿
爱范儿
J
Java Code Geeks
有赞技术团队
有赞技术团队
Blog — PlanetScale
Blog — PlanetScale
N
Netflix TechBlog - Medium
B
Blog
Stack Overflow Blog
Stack Overflow Blog
GbyAI
GbyAI
T
The Blog of Author Tim Ferriss
小众软件
小众软件
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Y
Y Combinator Blog
大猫的无限游戏
大猫的无限游戏
Microsoft Azure Blog
Microsoft Azure Blog
T
Tailwind CSS Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

博客园 - 云编程的梦

OpenGL超级宝典笔记5 libxml2对XML文件的创建、解析、查找、修改 [置顶] 我的设计模式学习笔记------>单例模式(Singleton) libxml2.7.8 c++ 解析xml文件 Head First设计模式-模板方法模式 嵌入式开发之工具移植--openssl移植 嵌入式开发之工具移植--wpa_suppliant工具的移植和使用 linux下嵌入式wifi开发工具移植 IOS面试题(英文) java提高篇-----理解java的三大特性之继承 staruml使用教程 黑马程序员:HTML习题1 Cocos2d-x-->CCSprite 动画 地址栏传参中文乱码详解 Qt学习第二天 Lync 2010 升级到2013 之部署2013前端服务器! 100层楼摔鸡蛋问题 Lync 2010升级到Lync 2013之更新CU2! eCos启动过程详解,基于Cortex-M架构
C++读写XML文件(libxml2库)
云编程的梦 · 2013-10-17 · via 博客园 - 云编程的梦

C++程序有时候要读写XML文件, 这里介绍一个读写XML文件的库——Libxml2。

主页:http://xmlsoft.org/index.html

入门教程很详细的:http://jianlee.ylinux.org/Computer/C/libxml.html#sec11

读取节点内容的话用XPath方式比较好,要问XPath与Libxml2库之间的关系,有个很形象的比喻:

那就是SQL与数据库之间的关系。

下面的代码是在Linux下实现的:

  1. #ifndef __XML_FILE_H__  
  2. #define __XML_FILE_H__  
  3.   
  4. #include <stdio.h>  
  5. #include <stdlib.h>  
  6. #include <libxml/parser.h>  
  7. #include <libxml/tree.h>  
  8. #include <map>  
  9. #include <string>  
  10. #include <iostream>  
  11.   
  12. using namespace std;  
  13.   
  14. const int XML_READ = 1;  
  15. const int XML_WRITE = 0;  
  16.   
  17. typedef struct _XML_INFO XML_INFO;  
  18. typedef struct _XML_INFO* HXML_INFO;  
  19.   
  20. struct _XML_INFO  
  21. {  
  22.     char version[16];  
  23.     int update;  
  24.     int scan_speed;  
  25.     int type;  
  26.     int device_counts;  
  27.     int item_counts;  
  28.       
  29.     map<string, string> map_item_info;  
  30. };  
  31.   
  32. class CLibxml2  
  33. {  
  34. public:  
  35.     CLibxml2();  
  36.     ~CLibxml2();  
  37.   
  38.     CLibxml2(const char *xml_file_path, bool is_read);  
  39.   
  40.      
  41.  
  42.  
  43.  
  44.  
  45.  
  46.   
  47.     bool open(const char *xml_file_path, bool is_read);  
  48.       
  49.      
  50.  
  51.  
  52.  
  53.  
  54.   
  55.     bool parse_xml_file(const XML_INFO &xml_info);  
  56.   
  57.      
  58.  
  59.  
  60.  
  61.  
  62.   
  63.     bool save_xml_file(XML_INFO &xml_info);  
  64.   
  65. private:  
  66.      
  67.  
  68.  
  69.  
  70.  
  71.   
  72.     xmlNodePtr search_node_ptr(const char *sz_expr);  
  73.   
  74. private:  
  75.     char m_sz_path[512];  
  76.     xmlDocPtr m_pdoc_read;  
  77.     xmlNodePtr m_proot;  
  78. };  
  79.   
  80.   
  81. #endif // __XML_FILE_H__  
  1. #include "xml-file.h"  
  2. #include <string.h>  
  3. #include <libxml/xpath.h>  
  4. #include <libxml/xpathInternals.h>  
  5. #include <libxml/xmlmemory.h>  
  6. #include <libxml/xpointer.h>  
  7.   
  8. CLibxml2::CLibxml2()  
  9. {  
  10.     m_pdoc_read = NULL;  
  11.     m_proot = NULL;  
  12.     bzero(m_sz_path, sizeof(m_sz_path));  
  13. }  
  14.   
  15. CLibxml2::~CLibxml2()  
  16. {  
  17.     if (m_pdoc_read)  
  18.     {  
  19.         xmlFreeDoc(m_pdoc_read);  
  20.         m_pdoc_read = NULL;  
  21.   
  22.         xmlCleanupParser();  
  23.         xmlMemoryDump();  
  24.     }  
  25. }  
  26.   
  27. CLibxml2::CLibxml2(const char *xml_file_path, bool is_read)  
  28. {  
  29.     if (xml_file_path)  
  30.     {  
  31.         open(xml_file_path, is_read);  
  32.     }  
  33. }  
  34.   
  35. bool CLibxml2::open(const char *xml_file_path, bool is_read)  
  36. {  
  37.     bool bret = false;  
  38.       
  39.     m_pdoc_read = NULL;  
  40.     m_proot = NULL;  
  41.     bzero(m_sz_path, sizeof(m_sz_path));  
  42.       
  43.     if (xml_file_path)  
  44.     {  
  45.         strcpy(m_sz_path, xml_file_path);  
  46.   
  47.         if (is_read)  
  48.         {  
  49.             xmlKeepBlanksDefault(0);  
  50.             m_pdoc_read = xmlReadFile(xml_file_path, "UTF-8", XML_PARSE_RECOVER);  
  51.             m_proot = xmlDocGetRootElement(m_pdoc_read);  
  52.         }  
  53.           
  54.         if (m_proot)  
  55.         {  
  56.             bret = true;  
  57.         }  
  58.     }  
  59.   
  60.     return bret;  
  61. }  
  62.   
  63. bool CLibxml2::parse_xml_file(XML_INFO &xml_info)  
  64. {  
  65.     bool bret = false;  
  66.     if (m_proot)  
  67.     {  
  68.         xmlNodePtr node = search_node_ptr("//config_Information");  
  69.         xmlChar *str = xmlGetProp(node, node->properties->name);  
  70.         strcpy(xml_info.version, (const char*)BAD_CAST(str));  
  71.           
  72.   
  73.         node = search_node_ptr("//Config_Data_block");  
  74.         str = xmlGetProp(node, node->properties->name);  
  75.         xml_info.update = atoi((const char*)BAD_CAST(str));  
  76.           
  77.   
  78.         node = search_node_ptr("//ScanSpeed");  
  79.         str = xmlNodeGetContent(node);  
  80.         xml_info.scan_speed = atoi((const char*)BAD_CAST(str));  
  81.           
  82.   
  83.         node = search_node_ptr("//DeviceType");  
  84.         str = xmlGetProp(node, node->properties->name);  
  85.         xml_info.type = atoi((const char*)BAD_CAST(str));  
  86.           
  87.   
  88.         node = search_node_ptr("//Device_Counts");  
  89.         str = xmlNodeGetContent(node);  
  90.         xml_info.device_counts = atoi((const char*)BAD_CAST(str));  
  91.           
  92.   
  93.         node = search_node_ptr("//Item_Counts");  
  94.         str = xmlNodeGetContent(node);  
  95.         xml_info.item_counts = atoi((const char*)BAD_CAST(str));  
  96.           
  97.   
  98.         int i;  
  99.         char item_id[32];  
  100.         char key_word[32];  
  101.         char id_content[32];  
  102.         char key_content[32];  
  103.         xmlNodePtr node_id;  
  104.         xmlNodePtr node_key;  
  105.           
  106.         for (i=1; i<=xml_info.item_counts; i++)  
  107.         {  
  108.             bzero(item_id, sizeof(item_id));  
  109.             bzero(key_word, sizeof(key_word));  
  110.             bzero(id_content, sizeof(id_content));  
  111.             bzero(key_content, sizeof(key_content));  
  112.               
  113.             sprintf(item_id, "//ItemInfo[%d]/ItemID", i);  
  114.             sprintf(key_word, "//ItemInfo[%d]/KeyWord", i);  
  115.             node_id = search_node_ptr(item_id);  
  116.             node_key = search_node_ptr(key_word);  
  117.             xmlChar *temp_id = xmlNodeGetContent(node_id);  
  118.             xmlChar *temp_key = xmlNodeGetContent(node_key);  
  119.             strcpy(id_content, (const char*)BAD_CAST(temp_id));  
  120.             strcpy(key_content, (const char*)BAD_CAST(temp_key));  
  121.             xml_info.map_item_info.insert(pair<string, string>(id_content, key_content));  
  122.         }  
  123.           
  124.         bret = true;  
  125.     }  
  126.   
  127.     return bret;  
  128. }  
  129.   
  130. bool CLibxml2::save_xml_file(const XML_INFO &xml_info)  
  131. {  
  132.     if (NULL == m_sz_path)  
  133.     {  
  134.         return false;  
  135.     }  
  136.   
  137.     char sz_temp[32];  
  138.       
  139.     xmlDocPtr pdoc = xmlNewDoc(BAD_CAST(xml_info.version));  
  140.     xmlNodePtr config_info = xmlNewNode(NULL, BAD_CAST"config_Information");  
  141.     xmlNewProp(config_info, BAD_CAST"version", BAD_CAST(xml_info.version));  
  142.     xmlDocSetRootElement(pdoc, config_info);  
  143.       
  144.     xmlNodePtr data_block = xmlNewNode(NULL, BAD_CAST"Config_Data_block");  
  145.     bzero(sz_temp, sizeof(sz_temp));  
  146.     sprintf(sz_temp, "%d", xml_info.update);  
  147.     xmlNewProp(data_block, BAD_CAST"update", BAD_CAST(sz_temp));  
  148.     xmlAddChild(config_info, data_block);  
  149.   
  150.     bzero(sz_temp, sizeof(sz_temp));  
  151.     sprintf(sz_temp, "%d", xml_info.scan_speed);  
  152.     xmlNewTextChild(data_block, NULL, BAD_CAST"ScanSpeed", BAD_CAST(sz_temp));  
  153.   
  154.     bzero(sz_temp, sizeof(sz_temp));  
  155.     sprintf(sz_temp, "%d", xml_info.type);  
  156.     xmlNodePtr device_type = xmlNewNode(NULL, BAD_CAST"DeviceType");  
  157.     xmlNewProp(device_type, BAD_CAST"type", BAD_CAST(sz_temp));  
  158.     xmlAddChild(data_block, device_type);  
  159.   
  160.     bzero(sz_temp, sizeof(sz_temp));  
  161.     sprintf(sz_temp, "%d", xml_info.item_counts);  
  162.     xmlNewTextChild(device_type, NULL, BAD_CAST"Item_Counts", BAD_CAST(sz_temp));  
  163.     int index = 1;  
  164.     int ncounts = xml_info.item_counts;  
  165.       
  166.     xmlNodePtr item_list = xmlNewNode(NULL, BAD_CAST"Item_list");  
  167.     xmlAddChild(device_type, item_list);  
  168.   
  169.     map<string, string>::iterator iter;  
  170.     for (iter=xml_info.map_item_info.begin();  
  171.          iter!=xml_info.map_item_info.end();  
  172.          ++iter)  
  173.     {  
  174.           
  175.         bzero(sz_temp, sizeof(sz_temp));  
  176.         sprintf(sz_temp, "%d", index++);  
  177.         xmlNodePtr item_info = xmlNewNode(NULL, BAD_CAST"ItemInfo");  
  178.         xmlNewProp(item_info, BAD_CAST"NO", BAD_CAST(sz_temp));  
  179.         xmlAddChild(item_list, item_info);  
  180.   
  181.         xmlNewTextChild(item_info, NULL, BAD_CAST"ItemID",  
  182.                         BAD_CAST((*iter).first.c_str()));  
  183.         xmlNewTextChild(item_info, NULL, BAD_CAST"KeyWord",  
  184.                         BAD_CAST((*iter).second.c_str()));  
  185.     }  
  186.       
  187.     xmlSaveFormatFileEnc(m_sz_path, pdoc, "UTF-8", 1);  
  188.     xmlFreeDoc(pdoc);  
  189.     return true;  
  190. }  
  191.   
  192. xmlNodePtr CLibxml2::search_node_ptr(const char *sz_expr)  
  193. {  
  194.     xmlNodePtr node_ret;  
  195.       
  196.     if (sz_expr == NULL)  
  197.     {  
  198.         return NULL;  
  199.     }  
  200.       
  201.     xmlChar *sz_path = BAD_CAST(sz_expr);  
  202.     xmlXPathContextPtr context = xmlXPathNewContext(m_pdoc_read);  
  203.     xmlXPathObjectPtr result = xmlXPathEvalExpression(sz_path, context);  
  204.       
  205.     if (result == NULL)  
  206.     {  
  207.         return NULL;  
  208.     }  
  209.     if (xmlXPathNodeSetIsEmpty(result->nodesetval))  
  210.     {  
  211.         return NULL;  
  212.     }  
  213.   
  214.     xmlXPathFreeContext(context);  
  215.       
  216.     node_ret = xmlXPtrBuildNodeList(result);  
  217.   
  218.     return node_ret;  
  219. }  
  220.   
  221.  
  222.  
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265. ///////////////////////////////  
  1. <?xml version="1.0"?>  
  2. <config_Information version="1.0">  
  3. <Config_Data_block update="0">  
  4. <ScanSpeed>100</ScanSpeed>  
  5. <DeviceType type="2">  
  6. <Device_Counts>1</Device_Counts>  
  7. <Item_Counts>6</Item_Counts>  
  8. <Item_list>  
  9. <ItemInfo NO="1">  
  10.     <ItemEvenFlag>1</ItemEvenFlag>  
  11.     <ItemID>CPU</ItemID>  
  12.     <KeyWord></KeyWord>  
  13. </ItemInfo>  
  14. <ItemInfo NO="2">  
  15.     <ItemID>MEM</ItemID>  
  16.     <KeyWord></KeyWord>  
  17. </ItemInfo>  
  18. <ItemInfo NO="3">  
  19.     <ItemID>DISK_C_FREE</ItemID>  
  20.     <KeyWord>C</KeyWord>  
  21. </ItemInfo>  
  22. <ItemInfo NO="4">  
  23.     <ItemID>RunTime</ItemID>  
  24.     <KeyWord></KeyWord>  
  25. </ItemInfo>  
  26. <ItemInfo NO="5">  
  27.     <ItemID>MainProcess0</ItemID>  
  28.     <KeyWord>test.exe</KeyWord>  
  29. </ItemInfo>  
  30. <ItemInfo NO="6">  
  31.     <ItemID>NetPing</ItemID>  
  32.     <KeyWord>127.0.0.1</KeyWord>  
  33. </ItemInfo>  
  34. </Item_list>  
  35. </DeviceType>  
  36. </Config_Data_block>  
  37. </config_Information>