zoukankan      html  css  js  c++  java
  • C++读写XML文件(libxml2库)

    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.       fn bool open(const char *xml_file_path, bool is_read) 
    42.       rief 打开一个XML文件是以读的方式还是以写的方式 
    43.       param in xml_file_path XML文件路径 
    44.       param in is_read true为读,false为写 
    45.        eturn true成功,false失败 
    46.     */  
    47.     bool open(const char *xml_file_path, bool is_read);  
    48.       
    49.     /*! 
    50.       fn bool parse_xml_file(XML_INFO &xml_info) 
    51.       rief 解析XML文件,将解析后的结果保存在XML_INFO结构体中 
    52.       param out xml_info 保存解析后的结果 
    53.        eturn true成功,false失败 
    54.     */  
    55.     bool parse_xml_file(const XML_INFO &xml_info);  
    56.   
    57.     /*! 
    58.       fn bool save_xml_file(const XML_INFO &xml_info) 
    59.       rief 写入XML文件 
    60.       param in xml_info 需要写入的信息 
    61.        eturn true成功,false失败 
    62.     */  
    63.     bool save_xml_file(XML_INFO &xml_info);  
    64.   
    65. private:  
    66.     /*! 
    67.       fn xmlNodePtr search_node_ptr(const char *sz_expr) 
    68.       rief 查找指定节点 
    69.       param in sz_expr 节点路径表达式(XPATH) 
    70.        eturn success返回指定节点指针,fail返回NULL 
    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.         //cout << xml_info.version << endl;  
    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.         //cout << xml_info.update << endl;  
    77.   
    78.         node = search_node_ptr("//ScanSpeed");  
    79.         str = xmlNodeGetContent(node);  
    80.         xml_info.scan_speed = atoi((const char*)BAD_CAST(str));  
    81.         //cout << xml_info.scan_speed << endl;  
    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.         //cout << xml_info.type << endl;  
    87.   
    88.         node = search_node_ptr("//Device_Counts");  
    89.         str = xmlNodeGetContent(node);  
    90.         xml_info.device_counts = atoi((const char*)BAD_CAST(str));  
    91.         //cout << xml_info.device_counts << endl;  
    92.   
    93.         node = search_node_ptr("//Item_Counts");  
    94.         str = xmlNodeGetContent(node);  
    95.         xml_info.item_counts = atoi((const char*)BAD_CAST(str));  
    96.         //cout << xml_info.item_counts << endl;  
    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. int main(void) 
    223. { 
    224.     //write///////////////////////////////// 
    225.     CLibxml2 lib("rmc1.xml", XML_WRITE); 
    226.  
    227.     map<string, string> map_item; 
    228.     XML_INFO xml_info; 
    229.     xml_info.map_item_info.insert(pair<string, string>("CPU", "")); 
    230.     xml_info.map_item_info.insert(pair<string, string>("MEM", "")); 
    231.     xml_info.map_item_info.insert(pair<string, string>("DISK_C_FREE", "C")); 
    232.     xml_info.map_item_info.insert(pair<string, string>("RunTime", "")); 
    233.     xml_info.map_item_info.insert(pair<string, string>("MainProcess0", "test.exe")); 
    234.     xml_info.map_item_info.insert(pair<string, string>("NetPing", "127.0.0.1")); 
    235.      
    236.     strcpy(xml_info.version, "1.0"); 
    237.     xml_info.update = 0; 
    238.     xml_info.scan_speed = 100; 
    239.     xml_info.type = 2; 
    240.     xml_info.device_counts = 2; 
    241.     xml_info.item_counts = xml_info.map_item_info.size(); 
    242.  
    243.     lib.save_xml_file(xml_info); 
    244.     ////////////////////////////////////////// 
    245.  
    246.  
    247.     //read///////////////////////////////////// 
    248.     XML_INFO xml_info; 
    249.     CLibxml2 lib("rmc.xml", XML_READ); 
    250.     lib.parse_xml_file(xml_info); 
    251.  
    252.     map<string, string>::iterator iter; 
    253.     for (iter = xml_info.map_item_info.begin(); 
    254.          iter != xml_info.map_item_info.end(); 
    255.          ++iter) 
    256.     { 
    257.         cout << (*iter).first << endl; 
    258.         cout << (*iter).second << endl; 
    259.     } 
    260.     //////////////////////////////////////////// 
    261.  
    262.     
    263.     return 0; 
    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> 
  • 相关阅读:
    DevOps工具链
    内网穿透工具
    SVN无法检出项目
    IDEA安装插件
    实习过程中学到关于各版本操作系统的知识(2)
    实习过程中学到关于各版本操作系统的知识(1)
    lib1funcs.S(用于解决裸板实现 printf 中的问题: undefined reference to `__aeabi_uidivmod' 和 undefined reference to `__aeabi_uidiv')
    交叉编译工具参数笔记
    vim 源码安装
    Git clone 下载慢解决方案
  • 原文地址:https://www.cnblogs.com/phisy/p/3373769.html
Copyright © 2011-2022 走看看