C++读写XML文件(Libxml2库)

来源:互联网 发布:自考本科 知乎 编辑:程序博客网 时间:2024/04/28 02:05

http://blog.csdn.net/tujiaw/article/details/7051432

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

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

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

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

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


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

[cpp] view plaincopyprint?
  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.     char version[16]; 
  22.     int update; 
  23.     int scan_speed; 
  24.     int type; 
  25.     int device_counts; 
  26.     int item_counts; 
  27.      
  28.     map<string, string> map_item_info; 
  29. }; 
  30.  
  31. class CLibxml2 
  32. public
  33.     CLibxml2(); 
  34.     ~CLibxml2(); 
  35.  
  36.     CLibxml2(const char *xml_file_path,bool is_read); 
  37.  
  38.     /*!
  39.       \fn bool open(const char *xml_file_path, bool is_read)
  40.       \brief 打开一个XML文件是以读的方式还是以写的方式
  41.       \param in xml_file_path XML文件路径
  42.       \param in is_read true为读,false为写
  43.       \return true成功,false失败
  44.     */ 
  45.     bool open(constchar *xml_file_path, bool is_read); 
  46.      
  47.     /*!
  48.       \fn bool parse_xml_file(XML_INFO &xml_info)
  49.       \brief 解析XML文件,将解析后的结果保存在XML_INFO结构体中
  50.       \param out xml_info 保存解析后的结果
  51.       \return true成功,false失败
  52.     */ 
  53.     bool parse_xml_file(const XML_INFO &xml_info); 
  54.  
  55.     /*!
  56.       \fn bool save_xml_file(const XML_INFO &xml_info)
  57.       \brief 写入XML文件
  58.       \param in xml_info 需要写入的信息
  59.       \return true成功,false失败
  60.     */ 
  61.     bool save_xml_file(XML_INFO &xml_info); 
  62.  
  63. private
  64.     /*!
  65.       \fn xmlNodePtr search_node_ptr(const char *sz_expr)
  66.       \brief 查找指定节点
  67.       \param in sz_expr 节点路径表达式(XPATH)
  68.       \return success返回指定节点指针,fail返回NULL
  69.     */ 
  70.     xmlNodePtr search_node_ptr(constchar *sz_expr); 
  71.  
  72. private
  73.     char m_sz_path[512]; 
  74.     xmlDocPtr m_pdoc_read; 
  75.     xmlNodePtr m_proot; 
  76. }; 
  77.  
  78.  
  79. #endif // __XML_FILE_H__ 

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

[html] view plaincopyprint?
  1. <?xmlversion="1.0"?> 
  2. <config_Informationversion="1.0"> 
  3. <Config_Data_blockupdate="0"> 
  4. <ScanSpeed>100</ScanSpeed> 
  5. <DeviceTypetype="2"> 
  6. <Device_Counts>1</Device_Counts> 
  7. <Item_Counts>6</Item_Counts> 
  8. <Item_list> 
  9. <ItemInfoNO="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> 

原创粉丝点击