analyzeXml格式化xml文件缩进格式

    技术2022-06-09  44

    /*************************************************************** * 函数名称:函数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,失败则返回-1struct 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,失败则返回-1struct 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)