analyzeXml格式化xml文件缩进格式_EnxXml还原xml缩进格式

/***************************************************************
 * 函数名称:函数analyzeXml会把XML格式文档格式化成标准缩进格式
             每次缩进4个空格
 * 功能描述:会把XML格式文档格式化成标准缩进格式
             每次缩进4个空格

 * 局限性: 对'>'和'<'之间的所有字符全部删除,比如换行符,空格等。
            为避免数据泥团,使用struct varWork类型

 * 输入参数:
     varWork &p = struct varWork类型
 返回参数:
     int 值0  ,代表正常结束;
 * 外部依赖:
 * 写作时间:2011.05.31 1.0版
 * 修改时间:2011.05.31 1.1版
             2011.05.31 1.2版,修正layer初始化值为-1,相当于重新确认root为第二行<...>节点,而不是第一行<?...?>
             2011.05.31 1.3版,修正类型:<!....>,包括<![CDATA[....]]>,不再进行区分
 * 用法举例:
 
  
  int main(string  DestDir,string strRet,string model = "r")
  {
  char* file1 = "E://RES//try.xml";
  char* Dir = file1;
  if ( getFileChar(Dir) == 0 )
  {
  printf("analyzeXml is success./n");
  }
  else
  {
  printf("analyzeXml is fail./n");
  }
 
    system("pause");
    return 0;
}
 *
 ****************************************************************/

#include <iostream>
#include <io.h>
#include <sys/utime.h>
using namespace std;

enum direction{Left,Right};

struct varWork
{
 //当前处理字符
 char ch;
 //缓冲字符
 char buffer;
 //查找目标类型,Left代表查找'<';Right代表查找'>'
 direction type;
 //信号量,0代表直接写入字符;1代表暂缓写入'<'字符;2代表写入endl、space*缩进数、"<X"字符
 int signal;
 //数据元素所在嵌套层次,初始化为0
 int layer;
 //本次'<'前,应该缩进的空格数,当出现</...>时会和layer不对应(元素结束行和元素起始行保持一致)
 int numSpace;
}p = {0,0,Left,0,-1,0};

//结构类型定义,结构变量;#include <sys/stat.h>的struct stat结构是stat函数可以返回的结构,
//里面包括文件的全部属性。返回值:若成功则返回0,失败则返回-1
struct stat s_buf;

//函数getFileChar负责按每个字符读写文件,文件级操作
int getFileChar (char *path);
//函数analyzeXml负责判断,把CR或LF格式转换成CR/LF文件格式
int analyzeXml(varWork &p);

int getFileChar (char *path )
{
 FILE *in, *out; //指向文件的指针,即FILE*文件流(管道应用);in用来读入,out用来输出。
    bool status = true;//表示已经出错状态,初始化为false,即暂时没出错。

 //缓冲临时文件路径,16字符的数组temppath,实际上除了结束符占一个字符外,只能存取15字符.
 char temppath [16];
 struct _utimbuf ut_buf; //在Windows NT和Windows95下,你可以改变utimbuf结构中的访问时间和修改时间。用来设定文件属性

 //建立一个临时文件。
    strcpy (temppath, "./clntmp");//把src所指由NULL结束的字符串复制到dest所指的数组中。
 strcat (temppath, "XXXXXX");//功能:把src所指字符串添加到dest结尾处(覆盖dest结尾处的'/0')并添加'/0'。
 mktemp (temppath);//mktemp()用来产生唯一的临时文件名。参数template所指的文件名称字符串中最后六个字符必须是XXXXXX。产生后的文件名会借字符串指针返回。
 // 返回值: 文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在errno中。
 
    //---打开文件----------------------------------------------------------------------
 if ((in=fopen (path, "rb")) == NULL)
 {
  //如果in等于NULL,即(FILE *) 0,表示打开文件失败,
  status = false;
 }
 else if ((out=fopen (temppath, "wb")) == (FILE *) NULL)
 {
  //如果out等于NULL,即(FILE *) 0,表示打开文件失败,
  //fclose(in)善后处理,取消本次不成功流程
  fclose (in);
  status = false;
 }
 else
 {
  //---开始转化,对每个字符进行遍历,处理后将写入临时文件----------------------------------------------------
  while ((p.ch = getc (in)) != EOF)
  {
   // 当ch也就是getc(in)的返回值不等于EOF文件尾结束符时,进行该循环;
      // getc功 能: 从流中取一个字符进行处理

   analyzeXml(p);

   switch (p.signal)
   {
   case 0:
    //直接写入字符
    putc(p.ch, out);
    if ( p.ch == '>')
    {
     p.signal = 1;
    }
    break;
   case 1:
    //暂缓写入,直至'<'字符解析完毕
    break;
   case 2:
    //排除第一行<?xml version="1.0" encoding="UTF-8" ?>前面出现空行的情况
    if ( p.ch != '?')
    {
     //代表写入endl、space*缩进数、"<X"字符
     
     //DOS换行符
     putc(0x0D, out);
     putc(0x0A, out);
     
     //缩进指定空格数
     for (int i = 0; i < p.numSpace; ++i)
     {
      putc(' ', out);
     }
    }
    
    //写入"<X"字符
    putc('<', out);
    putc(p.ch, out);
    
    //清空信号量,等待下次进入
    p.signal = 0;
    
    //修改查找类型,转为查找'>'
    p.type = Right;
    break;    
   default:
    printf("there may be one error in getFileChar./n");
    break;
   }

  } // while 结束,文件转化完毕
  
  printf("analyzeXml is success./n");
 } // else 结束
 
 //fclose若关闭文件动作成功则返回0,有错误发生时则返回EOF。流成功关闭,fclose 返回 0,否则返回EOF(-1)。
 if (fclose (in) == EOF)
 {
  status = false; //表示已经出错状态
 }

 if (fclose (out) == EOF)
 {
  status = false; //表示已经出错状态
 }
 
 //---后期处理----------------------------------------------------------------------
 ut_buf.actime = s_buf.st_atime; //最后一次访问的时间
 ut_buf.modtime = s_buf.st_mtime;//文件内容最后一次被更改的时间
 if (_utime (temppath, &ut_buf) == -1)//修改文件属性出错
  //#include <time.h> int utime(const char pathname, const struct utimbuf *times);返回值:成功返回0,失败返回-1
  status = false; //表示已经出错状态

 //原子性:1、删除原文件(成功);2、重名名临时文件为原文件(成功);3;删除临时文件(成功)---->成功
 //        1、删除原文件(成功);2、重名名临时文件为原文件(失败)---->出错提示,失败
 //        1、删除原文件(失败);2、删除临时文件---->失败
 //1、删除原文件,用unlink()函数来清除临时文件path,即删除原文件,成功返回0,失败返回-1。
 if (unlink (path) == 0 )
 {
  //删除原文件(成功)
  
  //2、重名名临时文件为原文件
  if ( rename (temppath,path) == 0 )
  {
   //3;删除临时文件
   unlink (temppath);//转换成功结束
  }
  else
  {
   //重命名出错提示
   fprintf (stderr, "Unix2Dos: Problems renaming '%s' to '%s'./n", temppath, path);
   fprintf (stderr, "          However, file '%s' remains./n", temppath);
   status = false;
  }
 }
 else
 {
  //删除原文件(失败)

  //删除临时文件
  unlink (temppath);//用unlink()函数来清除临时文件temppath,即删除原文件,成功返回0,失败返回-1。
  status = false; //出错状态,函数返回true。
 }
 
 return status ? 0 : 1;
}

int analyzeXml(varWork &p)
{
 //恢复正常缩进空格数
 p.numSpace = 4 * p.layer;

 switch ( p.type )
 {
 case Left:
  if ( p.ch == '<')
  {
   //开头<?.........?>,需要把信号量从0置为1,否则会多出一个<
   p.signal = 1;
  }
        else if ( p.buffer == '<' )
  {
   //已经存在'<',做后续判断
   switch ( p.ch)
   {
   case '?':
    //类型:<?
    //layer、numSpace保持不变
    break;
   case '/':
    //类型:</
    //layer减1,numSpace不减,元素结束行和元素起始行保持一致
    p.layer -= 1;
    break;
   case '!':
    //类型:<!....>,包括<![CDATA[....]]>
    //layer保持不变,numSpace增4
    p.numSpace += 4;
    break;
   default:
    //其他类型:<t...
    //layer增1,numSpace增4
    p.layer += 1;
    p.numSpace += 4;
    break;
   }
   
   //修改信号量,可以写入
   p.signal = 2;
  }
  break;
 case Right:
  if (p.ch == '>')
  {
   //按p.buffer进行判断
   switch (p.buffer)
   {
   case '/':
    //类型:/>
    //layer减1,numSpace减4
    p.layer -= 1;
    p.numSpace -= 4;
    break;
   case '?':
    //类型:?>
    //layer,numSpace保持不变
    break;
//   case ']':
//    //类型:<!....>,包括<![CDATA[....]]>,不再进行区分
//    //layer减1,numSpace减4
//    p.layer -= 1;
//    p.numSpace -= 4;
//    break;
   default:
    //其他类型:...t>
    //layer,numSpace保持不变
    break;
   }

   //修改查找类型,转为查找'<'
   p.type = Left;
  }
  break;
 default:
  printf("there may be one error in analyzeXml./n");
  break;
 }

 //缓冲字符,为"?>"类型作判断依据
 p.buffer = p.ch;

 return 0;
}

 

/***************************************************************
 * 函数名称:函数EnxXml会把XML格式文档还原成Enx特定格式文件
 * 功能描述:会把XML格式文档还原成Enx特定格式文件

 * 局限性: 对'>'和'<'之间的所有字符全部删除,比如换行符,空格等。
            为避免数据泥团,使用struct varWork类型

 * 输入参数:
     varWork &p = struct varWork类型
 返回参数:
     int 值0  ,代表正常结束;
 * 外部依赖:
 * 写作时间:2011.05.31 1.0版
 * 修改时间:2011.05.31 1.1版
 * 用法举例:
 
   int main(string  DestDir,string strRet,string model = "r")
   {
   char* file1 = "E://RES//try.xml";
   char* Dir = file1;
   if ( getFileChar(Dir) == 0 )
   {
   printf("EnxXml is success./n");
   }
   else
   {
   printf("EnxXml is fail./n");
   }
  
  system("pause");
  return 0;
}

 *
 ****************************************************************/

#include <iostream>
#include <io.h>
#include <sys/utime.h>
using namespace std;

enum direction{Left,Right};

struct varWork
{
 //当前处理字符
 char ch;
 //缓冲字符
 char buffer;
 //查找目标类型,Left代表查找'<';Right代表查找'>'
 direction type;
 //信号量,0代表直接写入字符;1代表暂缓写入'<'字符;2代表写入endl、space*缩进数、"<X"字符
 int signal;
 //数据元素所在嵌套层次,初始化为0
 int layer;
 //本次'<'前,应该缩进的空格数,当出现</...>时会和layer不对应(元素结束行和元素起始行保持一致)
 int numSpace;
}p = {0,0,Left,0,0,0};

//结构类型定义,结构变量;#include <sys/stat.h>的struct stat结构是stat函数可以返回的结构,
//里面包括文件的全部属性。返回值:若成功则返回0,失败则返回-1
struct stat s_buf;

//函数getFileChar负责按每个字符读写文件,文件级操作
int getFileChar (char *path);
//函数EnxXml负责判断,把CR或LF格式转换成CR/LF文件格式
int EnxXml(varWork &p);

int getFileChar (char *path )
{
 FILE *in, *out; //指向文件的指针,即FILE*文件流(管道应用);in用来读入,out用来输出。
    bool status = true;//表示已经出错状态,初始化为false,即暂时没出错。

 //缓冲临时文件路径,16字符的数组temppath,实际上除了结束符占一个字符外,只能存取15字符.
 char temppath [16];
 struct _utimbuf ut_buf; //在Windows NT和Windows95下,你可以改变utimbuf结构中的访问时间和修改时间。用来设定文件属性

 //建立一个临时文件。
    strcpy (temppath, "./clntmp");//把src所指由NULL结束的字符串复制到dest所指的数组中。
 strcat (temppath, "XXXXXX");//功能:把src所指字符串添加到dest结尾处(覆盖dest结尾处的'/0')并添加'/0'。
 mktemp (temppath);//mktemp()用来产生唯一的临时文件名。参数template所指的文件名称字符串中最后六个字符必须是XXXXXX。产生后的文件名会借字符串指针返回。
 // 返回值: 文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在errno中。
 
    //---打开文件----------------------------------------------------------------------
 if ((in=fopen (path, "rb")) == NULL)
 {
  //如果in等于NULL,即(FILE *) 0,表示打开文件失败,
  status = false;
 }
 else if ((out=fopen (temppath, "wb")) == (FILE *) NULL)
 {
  //如果out等于NULL,即(FILE *) 0,表示打开文件失败,
  //fclose(in)善后处理,取消本次不成功流程
  fclose (in);
  status = false;
 }
 else
 {
  //---开始转化,对每个字符进行遍历,处理后将写入临时文件----------------------------------------------------
  while ((p.ch = getc (in)) != EOF)
  {
   // 当ch也就是getc(in)的返回值不等于EOF文件尾结束符时,进行该循环;
      // getc功 能: 从流中取一个字符进行处理

   EnxXml(p);

   switch (p.signal)
   {
   case 0:
    //直接写入字符
    putc(p.ch, out);
    if ( p.ch == '>')
    {
     //清理掉'>'、'<'之间的换行符、空格等字符
     p.signal = 1;
    }
    break;
   case 1:
    //暂缓写入,直至'<'字符解析完毕
    break;
   default:
    printf("there may be one error in getFileChar./n");
    break;
   }

  } // while 结束,文件转化完毕
  
  printf("EnxXml is success./n");
 } // else 结束
 
 //fclose若关闭文件动作成功则返回0,有错误发生时则返回EOF。流成功关闭,fclose 返回 0,否则返回EOF(-1)。
 if (fclose (in) == EOF)
 {
  status = false; //表示已经出错状态
 }

 if (fclose (out) == EOF)
 {
  status = false; //表示已经出错状态
 }
 
 //---后期处理----------------------------------------------------------------------
 ut_buf.actime = s_buf.st_atime; //最后一次访问的时间
 ut_buf.modtime = s_buf.st_mtime;//文件内容最后一次被更改的时间
 if (_utime (temppath, &ut_buf) == -1)//修改文件属性出错
  //#include <time.h> int utime(const char pathname, const struct utimbuf *times);返回值:成功返回0,失败返回-1
  status = false; //表示已经出错状态

 //原子性:1、删除原文件(成功);2、重名名临时文件为原文件(成功);3;删除临时文件(成功)---->成功
 //        1、删除原文件(成功);2、重名名临时文件为原文件(失败)---->出错提示,失败
 //        1、删除原文件(失败);2、删除临时文件---->失败
 //1、删除原文件,用unlink()函数来清除临时文件path,即删除原文件,成功返回0,失败返回-1。
 if (unlink (path) == 0 )
 {
  //删除原文件(成功)
  
  //2、重名名临时文件为原文件
  if ( rename (temppath,path) == 0 )
  {
   //3;删除临时文件
   unlink (temppath);//转换成功结束
  }
  else
  {
   //重命名出错提示
   fprintf (stderr, "Unix2Dos: Problems renaming '%s' to '%s'./n", temppath, path);
   fprintf (stderr, "          However, file '%s' remains./n", temppath);
   status = false;
  }
 }
 else
 {
  //删除原文件(失败)

  //删除临时文件
  unlink (temppath);//用unlink()函数来清除临时文件temppath,即删除原文件,成功返回0,失败返回-1。
  status = false; //出错状态,函数返回true。
 }
 
 return status ? 0 : 1;
}

int EnxXml(varWork &p)
{
 switch ( p.type )
 {
 case Left:
  if ( p.ch == '<')
  {
   //开始正常写入
   p.signal = 0;

   //修改查找类型,转为查找'>'
   p.type = Right;
  }

  break;
 case Right:
  if ( p.ch == '>')
  {
   //修改查找类型,转为查找'<'
   p.type = Left;
  }
  break;
 default:
  printf("there may be one error in EnxXml./n");
  break;
 }

 return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值