示例#1
0
void ROXML_API roxml_del_node(node_t * n) 
{
	if(n == NULL) return;
	if(n->type & ROXML_ELM_NODE) {
		roxml_del_std_node(n);
	} else if(n->type & ROXML_ATTR_NODE) {
		roxml_del_arg_node(n);
	} else if(n->type & ROXML_PI_NODE) {
		roxml_del_std_node(n);
	} else if(n->type & ROXML_CMT_NODE) {
		roxml_del_std_node(n);
	} else if(n->type & ROXML_TXT_NODE) {
		roxml_del_txt_node(n);
	}
	roxml_free_node(n);
}
示例#2
0
文件: roxml.c 项目: cpoyet/DdraftDolo
void ROXML_API roxml_close(node_t *n)
{
	node_t *root = n;
	if(root == NULL)	{
		return;
	}
	while(root->prnt != NULL)	{
		root = root->prnt;
	}

	roxml_del_tree(root->chld);
	roxml_del_tree(root->sibl);
	if((root->type & ROXML_FILE) == ROXML_FILE)	{
		fclose(root->src.fil);
	}
	roxml_free_node(root);
}
int _func_load_close_node(char * chunk, void * data)
{
#ifdef DEBUG_PARSING
	fprintf(stderr, "calling func %s chunk %c\n",__func__,chunk[0]);
#endif /* DEBUG_PARSING */
	int cur = 1;
	roxml_load_ctx_t *context = (roxml_load_ctx_t*)data;

	switch(context->state) {
		case STATE_NODE_NAME:
			context->empty_text_node = 1;
			context->current_node = roxml_parent_node(context->current_node, context->candidat_node, 0);
		break;
		case STATE_NODE_ATTR:
			if((context->mode != MODE_COMMENT_DQUOTE)||(context->mode != MODE_COMMENT_QUOTE)) {
				if(context->inside_node_state == STATE_INSIDE_VAL)      {
					node_t * to_be_closed = NULL;
					if(context->content_quoted) {
						context->content_quoted = 0;
						to_be_closed = roxml_create_node(context->pos-1, context->src, ROXML_ATTR_NODE | context->type);
					} else {
						to_be_closed = roxml_create_node(context->pos, context->src, ROXML_ATTR_NODE | context->type);
					}
					roxml_close_node(context->candidat_val, to_be_closed);
				}
				context->current_node = roxml_parent_node(context->current_node, context->candidat_node, 0);
				context->inside_node_state = STATE_INSIDE_ARG_BEG;
				roxml_process_unaliased_ns(context);
			} else {
				context->pos++;
				return 1;
			}
		break;
		case STATE_NODE_SINGLE:
			if(context->doctype) {
				context->doctype--;
				if(context->doctype > 0) {
					context->pos++;
					return 1;
				}
				context->candidat_node->end = context->pos;
			}
			context->empty_text_node = 1;
			context->current_node = roxml_parent_node(context->current_node, context->candidat_node, 0);
			if(context->current_node->prnt != NULL) { context->current_node = context->current_node->prnt; } 
			roxml_process_unaliased_ns(context);
		break;
		case STATE_NODE_END:
			context->empty_text_node = 1;
			roxml_close_node(context->current_node, context->candidat_node);
			context->candidat_node = NULL;
			if(context->current_node->prnt != NULL) { context->current_node = context->current_node->prnt; }
		break;
		case STATE_NODE_CDATA:
		case STATE_NODE_CONTENT:
		default:
			context->pos++;
			return 1;
		break;
	}

	if(context->candidat_node && context->candidat_node->ns && ((context->candidat_node->ns->type & ROXML_INVALID) == ROXML_INVALID)) {
		roxml_free_node(context->candidat_node->ns);
	}

	context->state = STATE_NODE_CONTENT;
	context->previous_state = STATE_NODE_CONTENT;
	context->candidat_txt = roxml_create_node(context->pos+1, context->src, ROXML_TXT_NODE | context->type);
#ifdef IGNORE_EMPTY_TEXT_NODES
	while(chunk[cur] != '\0') { 
		if(chunk[cur] == '<') { break; }
		else if(!ROXML_WHITE(chunk[cur])) { context->empty_text_node = 0; break; }
		cur++; 
	}
#endif /* IGNORE_EMPTY_TEXT_NODES */
	while((chunk[cur] != '<')&&(chunk[cur] != '\0')) { cur++; }

	context->pos += cur;
	return cur;
}
int _func_load_default(char * chunk, void * data)
{
	node_t * to_be_closed;
	int cur = 1;
	roxml_load_ctx_t *context = (roxml_load_ctx_t*)data;
#ifdef DEBUG_PARSING
	fprintf(stderr, "calling func %s chunk %c\n",__func__,chunk[0]);
#endif /* DEBUG_PARSING */

	switch(context->state) {
		case STATE_NODE_SINGLE:
			context->state = context->previous_state;
		break;
		case STATE_NODE_BEG:
			if(context->ns == 0) {
				roxml_process_begin_node(context, context->pos-1);
			}
			context->ns = 0;
			context->state = STATE_NODE_NAME;
			context->curr_name = chunk;
			while(!ROXML_WHITE(chunk[cur])&&(chunk[cur] != '>')&&(chunk[cur] != '/')&&(chunk[cur] != ':')&&(chunk[cur] != '\0')) { cur++; }
			context->curr_name_len = cur;
		break;
		case STATE_NODE_ATTR:
			if(context->inside_node_state == STATE_INSIDE_ARG_BEG)  {
				if(context->nsdef) {
					if(context->namespaces == NULL) {
						context->namespaces = context->candidat_arg;
						context->last_ns = context->candidat_arg;
					} else {
						context->last_ns->next = context->candidat_arg;
						context->last_ns = context->candidat_arg;
					}
				} else if(context->ns == 0) {
					context->candidat_arg = roxml_create_node(context->pos-1, context->src, ROXML_ATTR_NODE | context->type);
					context->candidat_arg = roxml_parent_node(context->candidat_node, context->candidat_arg, 0);
				}
				context->ns = 0;
				context->inside_node_state = STATE_INSIDE_ARG;
				context->curr_name = chunk;
				while((chunk[cur] != '=')&&(chunk[cur] != '>')&&(chunk[cur] != ':')&&(chunk[cur] != '\0')) { cur++; }
				context->curr_name_len = cur;
				if(context->nsdef) {
					roxml_ns_t * ns = calloc(1, sizeof(roxml_ns_t)+(1+context->curr_name_len));
					ns->id = ROXML_NS_ID;
					ns->alias = (char*)ns + sizeof(roxml_ns_t);
					memcpy(ns->alias, context->curr_name, context->curr_name_len);
					context->candidat_arg->priv = ns;
					context->nsdef = 0;
					if(context->candidat_node->ns) {
						if((context->candidat_node->ns->type & ROXML_INVALID) == ROXML_INVALID) {
							if(strcmp(context->candidat_arg->prnt->ns->src.buf, ns->alias) == 0) {
								roxml_free_node(context->candidat_node->ns);
								context->candidat_node->ns = context->candidat_arg;
							}
						}
					}
				}
			} else if(context->inside_node_state == STATE_INSIDE_VAL_BEG)  {
				if(context->mode != MODE_COMMENT_NONE)     {
					context->content_quoted = 1;
					context->candidat_val = roxml_create_node(context->pos+1, context->src, ROXML_TXT_NODE | context->type);
				} else {
					context->candidat_val = roxml_create_node(context->pos, context->src, ROXML_TXT_NODE | context->type);
				}
				context->candidat_val = roxml_parent_node(context->candidat_arg, context->candidat_val, 0);
				context->inside_node_state = STATE_INSIDE_VAL;
			} else if((context->inside_node_state == STATE_INSIDE_ARG)&&(chunk[0] == '=')) {
				context->inside_node_state = STATE_INSIDE_VAL_BEG;
				to_be_closed = roxml_create_node(context->pos, context->src, ROXML_ATTR_NODE | context->type);
				roxml_close_node(context->candidat_arg, to_be_closed);
				if((context->curr_name_len==5)&&(strncmp(context->curr_name, "xmlns", 5) == 0)) {
					context->nsdef = 1;
				}
			}
		break;
	}

	context->pos += cur;
	return cur;
}