⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xml.c

📁 本人编写的利用XML来测试多个API接口函数的程序
💻 C
字号:
#include "xml.h"//#define DEBUGstatic char* align_string(char* pTemp){	int i = 0;	while(pTemp[i] == ' ')		i++;	return pTemp+i;}static int verifyxmlfile(int fd){	FILE* fp = fdopen(fd,"r");	char buf[255];	memset(buf,0,255);	if(!(fgets(buf,255,fp)))	{			return -1;	}	if(strncmp(buf,"<?",2) || !strstr(buf,"?>"))	{			return -1;	}	if(!strstr(buf,"Xml") && !strstr(buf,"xml"))	{			return -1;	}	return 0;}static struct element* tonext(struct element* elem,int* layer){	struct element* cur = NULL,*next = NULL;	cur = elem;	upfloor:	(*layer)--;	next = cur->parent;	if(!next)		return NULL;	if(next->brothers)		return next->brothers;	cur = next;	goto upfloor;}//***************************************************************************//1.struct xml* readxmlfile(char* filename){	struct xml* myxml = NULL;	int fd,size;	struct stat s;		if(!filename || (fd = open(filename,O_RDONLY)) < 0)	{		return NULL;	}	if(verifyxmlfile(fd) < 0)	{		fprintf(stderr,"verify xml file %s error!\n",filename);		close(fd);		return NULL;	}	if(!(myxml = malloc(sizeof(struct xml))))	{		close(fd);		return NULL;	}	memset(myxml,0,sizeof(struct xml));	strcpy(myxml->filename,filename);	myxml->root = myxml->current = NULL;	fstat(fd,&s);	myxml->size = s.st_size;		if(!(myxml->data = malloc(myxml->size + 10)))	{		free(myxml);		close(fd);		return NULL;	}	lseek(fd,0,SEEK_SET);	size = read(fd,myxml->data,myxml->size);	if(size != myxml->size)	{		fprintf(stderr,"read xml file %s failed\n",myxml->filename);		close(fd);		free(myxml->data);			free(myxml);		return NULL;	}	close(fd);	return myxml;		}static void freeelement(struct element* cur){	struct element_property* ep = cur->property,*next = NULL;	 while(ep)	{		next = ep->next;		free(ep);		ep = next;	}	free(cur);	return;}//***************************************************************************//2.int closexml(struct xml* myxml){	struct element *cur,*next,*parent;	if(!(myxml->data))		free(myxml->data);		cur = myxml->root;		while(cur)	{		if(cur->children)			cur = cur->children;		else if(cur->brothers)		{			next = cur->brothers;			parent = cur->parent;			parent->children = next;			#ifdef DEBUG			fprintf(stderr,"free element:%s success\n",cur->name);			#endif			freeelement(cur);			cur = next;		}		else		{			next = cur->parent;			if(next)				next->children = NULL;			#ifdef DEBUG			fprintf(stderr,"free element:%s success\n",cur->name);			#endif			freeelement(cur);			cur = next;				}	}	free(myxml);	return 0;}#define STATE_WILL_START  	0#define STATE_ELEM_NAME  	1#define STATE_ELEM_NAME_END 	2#define STATE_PROP_NAME  	3#define STATE_PROP_NAME_END 	4#define STATE_PROP_VALUE 	5#define STATE_PROP_VALUE_END 	6#define STATE_PROP_ONE_END 	7#define STATE_PROP_END 		8#define STATE_ELEM_VALUE 	9#define STATE_ELEM_VALUE_END 	10#define STATE_ELEM_END 		11#define STATE_END 		12#define KINDRED_PC	1  //parent--child#define KINDRED_CP 	2  //child---parentstruct __control {	int layer;  //0: top layer 	int state;  //	int kindred;  //前一个元素和新元素的关系;};static int findendtag(char* data,char* tag){	char buf[ELEMENT_MAX_SIZE + 5];	int n;	n = sprintf(buf,"</%s>",tag);	buf[n] = '\0';	if((strstr(data,buf)))		return 0;	else		return -1;}//***************************************************************************//3.int parsexmlfile(struct xml* myxml){	char* data,*offset,*tmp;	char suffix,buffer[512];	int size,count = 0;	struct element*  current= NULL,*parent = NULL;	struct element_property* cur_property = NULL;	char* pos = NULL;	int n;	struct __control control;	if(!myxml->data)		return -1;		control.layer = 0;	control.state = STATE_WILL_START;	control.kindred = 0;	data = offset = myxml->data;	size = myxml->size;	#ifdef DEBUG	fprintf(stderr,"=============>data begin address:%p\tsize:%d\n",data,size);	#endif	while((offset - data) < size )	{		switch(control.state)		{		case STATE_WILL_START:			findroot:			if(!(tmp = strchr(offset,'<')))				return -1;			suffix = *(tmp + 1);			if(suffix == '?' || suffix == '!')			{				offset = tmp + 1;				goto findroot;			}			if(suffix == ' ')				return -1;			offset = tmp + 1;			count = 0;			control.state = STATE_ELEM_NAME;					break;		case STATE_ELEM_NAME:			if(*offset != ' ' && *offset !=  '>' && *offset != '/')			{				buffer[count++] = *offset;				offset++;			}			else			{				buffer[count] = '\0';				count = 0;				control.state = STATE_ELEM_NAME_END;			}						break;		case STATE_ELEM_NAME_END:			control.layer++;			parent = current;			if(!(current = (struct element*)malloc(sizeof(struct element))))			{				#ifdef DEBUG				fprintf(stderr,"malloc memory of element<%s>failed!\n",						buffer);				#endif				return -1;			}			strcpy(current->name,buffer);			current->property = NULL;			current->value_size = findendtag(offset,buffer);			current->value[0] = '\0';			current->parent = NULL;			current->children = NULL;			current->brothers = NULL;			current->reserve = NULL;			#ifdef DEBUG				fprintf(stderr,"get one element: name %s \tlayer:%d\n",					current->name,control.layer);			#endif			if(control.layer == 1)			{				current->parent = NULL;				myxml->root = current;				parent = current;			}			else			{				if(!parent->children)				{					current->parent = parent;					parent->children = current;					parent->reserve = current;				}				else				{					current->parent = parent;					parent->reserve->brothers = current;					parent->reserve = current;				}			}			control.state = STATE_PROP_ONE_END;			break;		case STATE_PROP_NAME:			offset = align_string(offset);			if(*offset == '>' || *offset == '/')			{				return -1;			}			if(*offset != '=')			{				buffer[count++] = *offset;				offset++;			}			else			{				buffer[count] = '\0';				count = 0;				control.state = STATE_PROP_NAME_END;			}				break;		case STATE_PROP_NAME_END:			#ifdef DEBUG			fprintf(stderr,"\tproperty name:%s\t",buffer);			#endif			if(!(cur_property = malloc(sizeof(struct element_property))))			{				fprintf(stderr,"malloc memory of property <%s> failed!\n",						buffer);				return -1;			}			strcpy(cur_property->name,buffer);			cur_property->value[0] = '\0';			cur_property->next = current->property;			current->property = cur_property;			offset++;			count = 0;			control.state = STATE_PROP_VALUE;			break;		case STATE_PROP_VALUE:			if(*offset != ' ' && *offset != '>' && *offset != '/')			{				if(*offset == '"')				{					offset++;					break;				}				buffer[count++] = *offset;				offset++;			}			else			{				buffer[count] = '\0';				count = 0;				control.state = STATE_PROP_VALUE_END;			}			break;		case STATE_PROP_VALUE_END:			#ifdef DEBUG			fprintf(stderr,"value:%s\n",buffer);			#endif			strcpy(current->property->value,buffer);			control.state = STATE_PROP_ONE_END;  			break;		case STATE_PROP_ONE_END:			offset = align_string(offset);			if(*offset == '>')			{				offset++;				control.state = STATE_PROP_END;			}  			else if(*offset == '/' && *(offset + 1) == '>')			{				if(control.layer == 1)				{					#ifdef DEBUG					fprintf(stderr,"parse xml success!\n");					#endif					control.state = STATE_END;					}				else				{					control.layer--;					current = parent;					parent = parent->parent;					if(!parent)						parent = myxml->root;					control.kindred = KINDRED_CP;					control.state = STATE_ELEM_END;					offset += 2;				}					}			else				control.state = STATE_PROP_NAME;			break;		case STATE_PROP_END:			if(*offset == '\r' || *offset == '\n' || *offset == '\t' || *offset == ' ')			{				offset++;				break;			}			count = 0;			control.state = STATE_ELEM_VALUE;			break;		case STATE_ELEM_VALUE:			if(*offset != '<')			{				buffer[count++] = *offset;				offset++;			}			else			{				if(!strncmp(offset,"<!--",4))				{					if(!(pos = strstr(offset,"-->")))						return -1;					offset = pos + 3;					delspecial:						if(*offset == '\r' || *offset == '\n' || *offset == '\t' || *offset == ' ')					{						offset++;						goto delspecial;					}					break;				}				buffer[count] = '\0';				if(count > 0)				{					strcat(current->value,buffer);					#ifdef DEBUG					fprintf(stderr,"\tget element value: %s\tcount:%d\n",							current->value,count);					#endif				}				count = 0;				control.state = STATE_ELEM_VALUE_END;			}			break;		case STATE_ELEM_VALUE_END:			if(*(offset + 1) == '/')			{				#ifdef DEBUG				fprintf(stderr,"child %s layer:%d ---> parent\n",					current->name,control.layer);				#endif				n = sprintf(buffer,"</%s>",current->name);				buffer[n] = '\0';				if((strncmp(offset,buffer,strlen(buffer))))				{					fprintf(stderr,"error:find tag %s failed!\n",buffer);					return -1;				}				if(control.layer == 1)				{					#ifdef DEBUG					fprintf(stderr,"parse xml success!\n");					#endif					control.state = STATE_END;					}				else				{					control.layer--;					current = parent;					parent = parent->parent;					if(!parent)						parent = myxml->root;					control.kindred = KINDRED_CP;					control.state = STATE_ELEM_END;					offset += n;				}			}			else			{				#ifdef DEBUG				fprintf(stderr,"parent %s ---> children\n",current->name);				#endif				control.kindred = KINDRED_PC;				control.state = STATE_ELEM_NAME;				offset++;			}			break;		case STATE_ELEM_END:			control.state = STATE_PROP_END;			break;		case STATE_END:			free(myxml->data);			myxml->data = NULL;			return 0;			break;		default:			offset++;			break;		}	}	return 0;}//***************************************************************************//4.int traversalxml(struct xml* myxml){	int layer = 0;	struct element *cur,*next;	char* tmp = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";	char buf[16];		if(!myxml)		return -1;	cur = myxml->root;		while(cur)	{		memset(buf,0,16);		strncpy(buf,tmp,layer);		fprintf(stderr,"%s%s\tvalue:%s\n",buf,cur->name,cur->value);		if(cur->children)		{			layer++;			cur = cur->children;		}		else if(cur->brothers)		{			cur = cur->brothers;		}		else		{			if(!(next = tonext(cur,&layer)))				return 0;			cur = next;		}	}	return 0;}//***************************************************************************//5.int getcurrentelement(struct xml* myxml,char* name,char* value){	if(!myxml || !myxml->current || !name)		return -1;	strcpy(name,myxml->current->name);	if(!value)		strcpy(value,myxml->current->value);	return 0;}//***************************************************************************//6.int getcurrentpath(struct xml* myxml,char* path,int size){	struct element *real[16],*cur;	int n,i,len = 0;	if(!myxml || !myxml->current || !path)		return -1;	path[0] = '\0';	cur = myxml->current;	for(n = 0;n < 16;n++)	{		if(!cur)			break;		real[n] = cur;		cur = cur->parent;	}	for(i = n - 2;i>= 0;i--)	{		len += strlen(real[i]->name) + 1;		if(len >= size)			return -1;		strcat(path,real[i]->name);		strcat(path,"/");	}	return 0;}//***************************************************************************//7.int movetoroot(struct xml* myxml){	if(!myxml || !myxml->root)		return -1;	myxml->current = myxml->root;	return 0;}//***************************************************************************//8.int movetoparent(struct xml* myxml){	struct element* parent;	if(!myxml || !myxml->current)		return -1;	parent = myxml->current->parent;	myxml->current = parent;	return 0;}struct element* match(struct element* head,char* elem){	struct element* current = NULL;	if(!head || !elem)		return NULL;	current = head;	while(current)	{		if(!strcmp(current->name,elem))			return current;		current = current->brothers;	}	return NULL;}//***************************************************************************//9.int movetochild(struct xml* myxml,char* elem){	struct element* cur = NULL;		if(!myxml || !myxml->current || !elem)		return -1;	cur = myxml->current->children;	if(!cur)		return -1;	cur = match(cur,elem);	if(cur)	{		myxml->current = cur;		return 0;	}	else		return -1;}//***************************************************************************//10.int movetobrother(struct xml* myxml,char* elem){	struct element* cur = NULL;		if(!myxml || !myxml->current || !elem)		return -1;	if(!strcmp(myxml->current->name,elem))		return 0;	cur = myxml->current->parent;	if(!cur)		return -1;	cur = cur->children;	if(!cur)		return -1;	cur = match(cur,elem);	if(cur)	{		myxml->current = cur;		return 0;	}	else		return -1;}//****************************************************************************//11.int movetofirstchild(struct xml* myxml){	if(!myxml || !myxml->current || !myxml->current->children)		return -1;	myxml->current = myxml->current->children;	return 0;}//****************************************************************************//12.int movetonextbrother(struct xml* myxml){	if(!myxml || !myxml->current || !myxml->current->brothers)		return -1;	myxml->current = myxml->current->brothers;	return 0;}//***************************************************************************//13.int getchildren(struct xml* myxml){	struct element* cur;	if(!myxml || !myxml->current)		return -1;	cur = myxml->current->children;	while(cur)	{		fprintf(stderr,"%s\t%s\n",cur->name,cur->value);		cur = cur->brothers;	}	fprintf(stderr,"\n");	return 0;}//***************************************************************************//14.int getcurrentproperty(struct xml* myxml,char* name,char* value,int size){	struct element_property* ep;	if(!myxml || !myxml->current || !name || !value)		return -1;	ep = myxml->current->property;	while(ep)	{		if(!strcmp(ep->name,name) && (strlen(ep->value) < size))		{			strcpy(value,ep->value);			return 0;		}			}	return -1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -