/*************************************************************** * 函数名称:函数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;}