XML 解析c++源码(源文件)

/*
 * XMLTool.cpp 配置文件解析动态库资源文件
 *  主要输出函数接口分别实现对配置文件的读取和写入,针对结果集的复制清空,和两个字符串处理函数
 *  读取配置文件接口 :int ReadXMLFile(XML_Node_Vector *XmlNodeVector, string filepath);
 *  写入配置文件接口 :int WriteXMLFile(XML_Node_Vector *XmlNodeVector, string filepath,bool is_addend = true);
 *  复制结构集接口  :bool VecDataCopy(XML_Node_Vector *XmlNodeVectorDest,const XML_Node_Vector *XmlNodeVectorSource);
 *  清空结构集接口      :bool VecDataClean(XML_Node_Vector *XmlNodeVector);
 *  字符串安全拷贝接口 :bool strncpy_ex(char *pStrDest,const char *pStrSource,int nDestSize);
 *  字符串安全处理接口  :bool printf_ex(char* szBuf,int nDestSize,char *szFormat, ...);
 *
 * 配置文件信息结构大概如下 注意 <> 符号包括其中的字符串仅为现在说名信息
 *
 * |[1234<节点头数据>]<节点头>
 * |abc<节点前信息体数据>=123<节点后信息体数据>
 * |123<节点前信息体数据>=890<节点后信息体数据>
 * | 
 * 注意:
 *  0.所有有效行数据必须顶格书写否者将不会读取该行数据,将作为无效数据处理 (所有无效数据将不予读取
 *   0.1:不顶格书写
 *   0.2:顶格第一个字符为 # 或 $
 *   0.3:顶格第一个字符为 =
 *  1.节点前信息体数据在读取数据的时候自动舍去空格,而节点后信息体数据不做处理,将原样读取
 *  2. # 和 $ 符号为注解符 遇到他们开始的行将不读取他们的数据 或者在不顶行书写
 *  3.具体数据结构请对照定义
 *
 * createtime:2010-1-26
 * edittime:2010-1-27
 * creator:seky.gu
 * editor;seky.gu
 * mingyao.gu@hp.com
 */

 

#include "XMLTool.h"
#include <stdarg.h>
#include <iostream>
#include <fstream>
using namespace std;


//返回值定义
#define RETURN_VALUE_SUCCESS    0//操作成功
#define RETURN_VALUE_PARAMETER_ERROR  1//非法参数
#define RETURN_VALUE_FILEOPEN_ERROR   2//文件打开出错
#define RETURN_VALUE_MEM_OPERATION_ERROR 3//文件打开出错
#define RETURN_VALUE_FILE_OPERATION_ERROR 4//文件内容不能构成至少一个节点

//注解符定义
#define COMMENT_CHAR_1      23   // '#'
#define COMMENT_CHAR_2      24   // '$'


      /*定义是否去掉头结点数据中的空格*/
#define COMMENT_CHAR_3     ' '  // 节点头的空格,这样定义将去掉节点头空格        默认去空格
//#define COMMENT_CHAR_3    '/0' // 节点头的空格,这样定义将不会去掉节点头空格
      /*定义是否去掉信息体等号前的空格*/
#define COMMENT_CHAR_4     ' '  // 节点信息体等号之前数据的空格,这样定义将去掉空格  默认去空格
//#define COMMENT_CHAR_4    '/0' // 节点信息体等号之前数据的空格,这样定义将保留空格
      /*定义是否去掉信息体等号后的空格*/
//#define COMMENT_CHAR_5    ' '  // 节点信息体等号之后数据的空格,这样定义将去掉空格  
#define COMMENT_CHAR_5     '/0' // 节点信息体等号之后数据的空格,这样定义将保留空格  默认保留空格


#define ASSERT_STL_EMPTY(item)/
 if(0 != item->GetItemCount()) return RETURN_VALUE_PARAMETER_ERROR
#define ASSERT_STL_NOEMPTY(item)/
 if(0 == item->GetItemCount()) return RETURN_VALUE_PARAMETER_ERROR
#define ASSERT_STLex_NOEMPTY(item)/
  if(0 == item->xml_node_vector.size()) return (RETURN_VALUE_PARAMETER_ERROR-1)
#define ZEROR_PVOID_MEMORY(data)/
 memset(data,0,sizeof(data))
#define ZEROR_STRING_MEMORY(data)/
 memset(&data,0,sizeof(data))


//函数实现
extern "C"
{
 /*  读取配置文件
  * int ReadXMLFile(XML_Node_Vector *XmlNodeVector, string filepath)
  *
  * XmlNodeVector 节点集结构体<具体见定义>
  * filepath 文件路径<绝对路径 包含文件名>
  *
  * return 返回处理结果<详见定义>
 */
 DECLDIR int ReadXMLFile(XML_Node_Vector *XmlNodeVector, string filepath)
 {
  //参数检查
  ASSERT_STL_EMPTY(XmlNodeVector);  
  if(filepath.empty())return RETURN_VALUE_PARAMETER_ERROR;
  //打开文件
  fstream fs_file(filepath.c_str(),ios::in);  
  if (fs_file.bad())
  {//打开出错处理
   return RETURN_VALUE_FILEOPEN_ERROR;
  }
  //定义中间变量
  char str_data[255] = {0};
  //char t_data_head[255] = {0};
  char t_data_first[255] = {0};
  char t_data_second[255] = {0};
  ZEROR_PVOID_MEMORY(str_data);
  //节点零时载体
  string first,second;
  XML_Node *temp_node;
  //字符定位变量
  int i = 0;//标记总字符串
  int j = 0;//标记信息体分段
  int fh_point = 0;//‘]’符号位标志
  int node_number = 0;//节点开始标识
  //循环读取文件信息 然后进行解析
  while(fs_file)
  {   
   //读取打开文件中一行数据
   fs_file.getline(str_data,sizeof(str_data));    
   if('/0' == str_data[0]||' ' == str_data[0]||'=' == str_data[0]||COMMENT_CHAR_1 == str_data[0]||COMMENT_CHAR_2 == str_data[0])
   {//无效行返回
    continue;
   }
   //解析数据
   else if('[' == str_data[0])
   {//头结点
    if(0 != node_number)
    {//加入结点     
     XmlNodeVector->InsertItem(*temp_node);
     ZEROR_STRING_MEMORY(temp_node);
    }
    //重新设置中间变量
    i = 0;
    j = 0;
    fh_point = 0;
    //去掉节点头最后一个 ‘]’ 开始之后的字符
    while('/0' != str_data[i++])
    {
     if((COMMENT_CHAR_3==str_data[i])||('/0'==str_data[i]))continue;     
     str_data[j++] = str_data[i];
     if(']' == str_data[i])fh_point = j-1;
    }
    if(0 >= fh_point)
    {
     ZEROR_PVOID_MEMORY(str_data);
     continue;
    } else
    {
     str_data[fh_point] = '/0';
    }    
    //申请新节点
    temp_node = (XML_Node*)new XML_Node;
    //设置新节点头
    //temp_node->node_title.assign(t_data_head); 
    temp_node->node_title.assign(str_data);
    //中间数据处理
    //ZEROR_PVOID_MEMORY(t_data_head);
    ZEROR_PVOID_MEMORY(str_data);
    node_number++;
   }else
   {//信息体 没有等号 或者等号在第一位依然属于无效行
    //重新设置中间变量
    if(0 == node_number)continue;
    i = 0;
    j = 0;
    while(('=' != str_data[i])&&('/0' != str_data[i]))
    {
     if(COMMENT_CHAR_4!=str_data[i])
      t_data_first[j++] = str_data[i];
     i++;
    }
    if((0==i)||('/0' == str_data[i]))
    {//没有等号 或者等号在第一位 依然属于无效行 舍弃之前获取的字符
     ZEROR_PVOID_MEMORY(t_data_first);
     continue;     
    }else
    {//合法信息体读取 ‘=’后面数据
     //重新设置中间变量
     i++;
     j = 0;
     while('/0' != str_data[i])
     { 
      (COMMENT_CHAR_5 != str_data[i])?t_data_second[j++]=str_data[i++]:i++;      
     }
     //将有效数据添加进数据集
     first.assign(t_data_first);
     second.assign(t_data_second);
     temp_node->InsertItem(first,second);
     ZEROR_STRING_MEMORY(first);
     ZEROR_STRING_MEMORY(second);
     ZEROR_PVOID_MEMORY(t_data_first);
     ZEROR_PVOID_MEMORY(t_data_second);
    }
   }
  }  
  if(0 < node_number)
  {//加入最后一个结点
   XmlNodeVector->InsertItem(*temp_node);
   ZEROR_STRING_MEMORY(temp_node);
  }
  //关闭文件流
  fs_file.close();
  if(0 == XmlNodeVector->GetItemCount())
  {//文件内容不能构成至少一个节点
   return RETURN_VALUE_FILE_OPERATION_ERROR;
  }else
  {  
   return RETURN_VALUE_SUCCESS;
  }
 }

 /*  将节点集数据写入配置文件
  * int WriteXMLFile(XML_Node_Vector *XmlNodeVector, string filepath,bool is_addend)
  *
  * XmlNodeVector 节点集结构体<具体见定义>
  * filepath 文件路径<绝对路径 包含文件名>
  * is_addend 写入类型<true 在文件末尾继续添加 false 将源文件内容更新为当前数据>
  *
  * return 返回处理结果<详见定义>
 */
 DECLDIR int WriteXMLFile(XML_Node_Vector *XmlNodeVector, string filepath,bool is_addend)
 {
  //参数检查
  ASSERT_STL_NOEMPTY(XmlNodeVector);
  if(filepath.empty())return RETURN_VALUE_PARAMETER_ERROR;
  //定义文件流对象
  fstream fs_file;
  //打开文件
  if(is_addend)
  {
   fs_file.open(filepath.c_str(),ios::out|ios::app);
  }else
  {
   fs_file.open(filepath.c_str(),ios::out);
  }  
  if (fs_file.bad())
  {//出错处理
   return RETURN_VALUE_FILEOPEN_ERROR;
  }
  //遍历节点将数据写入文件
  for(XmlNodeVector->node_item = XmlNodeVector->xml_node_vector.begin();
   XmlNodeVector->node_item!=XmlNodeVector->xml_node_vector.end();
   XmlNodeVector->node_item++)
  {//写入节点头   
   fs_file<<"["<<XmlNodeVector->node_item->node_title<<"]/n";   
   for(XmlNodeVector->node_item->boby_item=XmlNodeVector->node_item->xml_body.begin();
    XmlNodeVector->node_item->boby_item!=XmlNodeVector->node_item->xml_body.end();
    XmlNodeVector->node_item->boby_item++)
   {//写入节点数据体
    fs_file<<XmlNodeVector->node_item->boby_item->first<<"="<<XmlNodeVector->node_item->boby_item->second<<"/n";
   }
  }
  //关闭文件流
  fs_file.close();
  return RETURN_VALUE_SUCCESS;
 }

 /*  复制节点集信息
  * int DataCopy(XML_Node_Vector *XmlNodeVectorAim,const XML_Node_Vector *XmlNodeVectorSource);
  *
  * XmlNodeVectorAim 目标节点集结构体<具体见定义>
  * XmlNodeVectorSource 源节点集结构体<具体见定义>  
  *
  * return 返回处理结果<详见定义>
  */
 bool VecDataCopy(XML_Node_Vector *XmlNodeVectorDest,const XML_Node_Vector *XmlNodeVectorSource)
 { 
  //参数检查
  ASSERT_STL_EMPTY(XmlNodeVectorDest);
  ASSERT_STLex_NOEMPTY(XmlNodeVectorSource);
  //中间变量
  string first,second,title;
  XML_Node *temp_node;
  //遍历节点将数据写入文件
  unsigned int node_size = XmlNodeVectorSource->xml_node_vector.size();
  unsigned int data_size = 0;
  for(;
   node_size > 0;
   node_size--)
  {//写入节点头   
   //申请新节点
   temp_node = (XML_Node *)new XML_Node; 
   data_size = XmlNodeVectorSource->xml_node_vector.begin()->xml_body.size();
   for(;
    data_size > 0;
    data_size--)
   {//写入节点数据体
    //first
    first.assign(XmlNodeVectorSource->xml_node_vector.begin()->xml_body.begin()->first.c_str());
    //second
    second.assign(XmlNodeVectorSource->xml_node_vector.begin()->xml_body.begin()->second.c_str());
    //node_title
    title.assign(XmlNodeVectorSource->xml_node_vector.begin()->node_title.c_str());
    //insert data
    temp_node->InsertItem(first,second);
    temp_node->node_title.assign(title);
    //next
    XmlNodeVectorSource->xml_node_vector.begin()->xml_body.begin()++;
   }
   //insert data
   XmlNodeVectorDest->InsertItem(*temp_node);
   XmlNodeVectorDest->node_type = XmlNodeVectorSource->node_type;   
  } 
  return true;
 }


 /*  清空节点集信息
  * bool VecDataClean(XML_Node_Vector *XmlNodeVector);
  *
  * XmlNodeVector 待清空的目标节点集结构体<具体见定义>  
  *
  * return 返回处理结果<详见定义>
  */
 DECLDIR bool VecDataClean(XML_Node_Vector *XmlNodeVector)
 {
  XmlNodeVector->xml_node_vector.clear();
  XmlNodeVector->node_type = 0;
  XmlNodeVector->node_item = XmlNodeVector->xml_node_vector.begin();
 
  return true; 
 }
 /*  字符串安全拷贝函数(该函数检查了目标和源字符串的空间溢出问题,对于源字串长度不够填充目标字串采用0补位)
  * bool strncpy_ex(char *pD,const char *pS,int nDestSize);
  *
  * pStrDest 目标字串<char*>
  * pStrSource 源字串<char*>
  * nDestSize 从源字符串拷贝到目标字符串的字符串大小<建议传递sizeof(pStrDest)>
  *
  * return 返回处理结果<详见定义>
  */
 bool strncpy_ex(char *pCDest,const char *pCSource,int nDestSize)
 {
  int nLen=strlen(pCSource)+1;
  if(nLen>nDestSize) nLen=nDestSize;//处理源字符串不够长的问题
  memcpy(pCDest,pCSource,nLen);
  *(pCDest+nLen-1)='/0';//处理源字符串不够长在最后添加结尾符

  return true;
 }

 /*  字符串安全处理函数(该函数检查了目标和源字符串的空间溢出问题,对于源字串长度不够填充目标字串采用0补位)
  * bool printf_ex(char* szBuf,int nDestSize,char *szFormat, ...);
  *
  * szBuf, nDestSize,szFormat,... .. .待处理的参数列表<具体参见 c++ nsprintf(... .. .)函数>  
  *
  * return 返回处理结果<详见定义>
  */
 bool printf_ex(char* szBuf,int nDestSize,char *szFormat, ...)
 {
  int nListCount=0;
  va_list pArgList;
  va_start (pArgList,szFormat);
  nListCount+=_vsnprintf(szBuf+nListCount,
   nDestSize-nListCount,szFormat,pArgList);
  va_end(pArgList);
  *(szBuf+nDestSize-1)='/0';
  return strlen(szBuf);
 
  return true;
 }
}

 

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值