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

📄 xmlanalyzer.c

📁 基于Vxworks平台的几个代码(C)
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "xmlAnalyzer.h"


/* 全局变量 */
static SEM_ID	XML_ANALYZER_LOCK = NULL;	/* XML分析器互斥量 */
static UINT32   XML_TEXT_LINE;				/* 表示当前正在分析的文本行 */



/************************************* TAG堆栈(内部) *************************************/

/* 堆栈元素结构 */
typedef struct
{
	char TagName[MAX_NAME_CHAR + 1];/* 标识名 */
	int  AttrNum;					/* 属性个数 */
}XML_STACK_NODE;

/* 全局标识堆栈 */
static struct
{
	int            top;
	XML_STACK_NODE node[MAX_NEST_NUMBER];
}XML_TAG_STACK;


/* 函数功能: 初始化堆栈 */
void xmlTagStack_Init( void )
{
	memset( &XML_TAG_STACK, 0, sizeof(XML_TAG_STACK) );
	XML_TAG_STACK.top = -1;
}

/* 函数功能: 入栈 */
BOOL xmlTagStack_Push( const XML_STACK_NODE *node )
{
	BOOL ret = FALSE;
	
	if( XML_TAG_STACK.top + 1 < MAX_NEST_NUMBER )
	{
		XML_TAG_STACK.node[++XML_TAG_STACK.top] = (*node);
		ret = TRUE;
	}
	
	return ret;
}

/* 函数功能: 出栈 */
BOOL xmlTagStack_Pop( XML_STACK_NODE *node )
{
	BOOL ret = FALSE;
	
	if( XML_TAG_STACK.top > -1 )
	{
		(*node) = XML_TAG_STACK.node[XML_TAG_STACK.top--];
		ret = TRUE;
	}
	
	return ret;
}

/* 函数功能: 检查堆栈是否为空 */
BOOL xmlTagStack_IsEmpty( void )
{
	return XML_TAG_STACK.top == -1;
}


/************************************* 多叉树函数(内部) *************************************/
/* 函数功能: 创建多叉树 */
TREE_ROOT* xmlTreeBuild( void )
{
	TREE_ROOT *root;
	
	root = malloc( sizeof(TREE_ROOT) );
	if( root )
	{
		memset( root, 0, sizeof(TREE_ROOT) );
	}
	
	return root;
}

/* 函数功能: 释放多叉树 */
void xmlTreeRelease( TREE_ROOT *root )
{
	if( root )
	{
		/* 删除root下的所有树枝 */
		while( root->son )
		{
			xmlTreeCut( root, root->son );
		}
		
		/* 删除根 */
		free( root );
	}
}

/* 函数功能: 按指定路径定位结点
*  参数:
*  root[IN]:
*  path[IN]: 查找路径, 路径格式为: dir_1.dir_2.[...]
*  如果某子目录需要按集合方式寻址: dir_1.dir_2[3].[...]
*/
TREE_NODE* xmlTreeReach( TREE_ROOT  *root,
						 char       *path
						 )
{
	char      name[MAX_NAME_CHAR + 20];
	int       i, n, s1, s2;
	TREE_NODE *son = NULL;
	
	
	if( root && path )
	{
		s1 = 0;
		s2 = strlen( path );
		son = root->son;
		
		while( son && s1 < s2 )
		{
			/* 提取path中的子目录 */
			if( p_substr2(path + s1, 1, name, sizeof(name), '.') != 0 )
			{
				son = NULL;
				
#if (XML_SHOW_DEBUG_INFO == TRUE)
				logMsg( "函数(xmlTreeReach)返回失败, %s, %d\n", __FILE__, __LINE__ );
#endif
				break;
			}
			s1 += strlen( name ) + 1;
			
			/* 确定子目录是否为集合 */
			p_strtrim( name );
			i = strlen(name) - 1;
			if( name[i] == ']' )
			{
				for( i--; i > 0; i-- )
				{
					if( name[i] == '[' )
					{
						if( name[i + 1] != ']' )
						{
							name[i] = '\0';
							n = atoi( name + i + 1 );/* 获取下标值 */
						}
						else
						{
							i = -1;/* path表达式不正确, []中不能为空 */
							
#if (XML_SHOW_DEBUG_INFO == TRUE)
							logMsg( "函数(xmlTreeReach)返回失败, %s, %d\n", __FILE__, __LINE__ );
#endif
						}
						break;
					}
					else if( name[i] < '0' || name[i] > '9' )
					{
						i = -1;/* path表达式不正确, []中必须是数字 */
						
#if (XML_SHOW_DEBUG_INFO == TRUE)
						logMsg( "函数(xmlTreeReach)返回失败, %s, %d\n", __FILE__, __LINE__ );
#endif
						break;
					}
				}
				
				i = i > 0 ? i : -1;
			}
			else
			{
				n = 0;
			}
			
			if( i == -1 )
			{
				/* 异常结束 */
				son = NULL;
				
#if (XML_SHOW_DEBUG_INFO == TRUE)
				logMsg( "函数(xmlTreeReach)返回失败, %s, %d\n", __FILE__, __LINE__ );
#endif
				break;
			}
			

			/* 从当前树枝结点开始向下查找(左遍历) */
			while( son )
			{
				if( strcmp(son->ele.Name, name) == 0 )
				{
					if( (--n) < 0 )
					{
						/* 匹配成功 */
						if( s1 < s2 )
						{
							/* 将继续查找下一级 */
							son = son->son;
						}
						break;
					}
					else
					{
						/* 将继续查找符合下标的结点 */
						son = son->next;
					}
				}
				else
				{
					son = son->next;
				}
			}/* while( son ) */
		}/* while( son && s1 < s2 ) */
		
		if( son )
		{
			/* 设置当前结点位置 */
			root->cur = son;
		}
#if (XML_SHOW_DEBUG_INFO == TRUE)
		else
		{
			logMsg( "函数(xmlTreeReach)返回失败, %s, %d\n", __FILE__, __LINE__ );
		}
#endif
	}
#if (XML_SHOW_DEBUG_INFO == TRUE)
	else
	{
		logMsg( "函数(xmlTreeReach)返回失败, %s, %d\n", __FILE__, __LINE__ );
	}
#endif
	
	return son;
}

/* 函数功能: 删除树枝 */
void xmlTreeCut( TREE_ROOT *root,
				 TREE_NODE *node
				 )
{
	int i;
	TREE_NODE *son, *tmp;
	
	if( root && node )
	{
		/* 删除该树枝下的所有结点, 使用递推法 & 回溯法逐个删除结点(左遍历方式) */
		son = node;
		while( son )
		{	
			/* 递推至最后一个儿子 */
			while( son->son )
			{
				son = son->son;
			}
			
			if( root->cur == son )
			{
				/* 设置当前结点位置 */
				root->cur = NULL;
			}
			
			/* 删除结点内容即ele */
			free( son->ele.Name );	/* 释放元素名存储区 */
			if( son->ele.Value )
				free( son->ele.Value );/* 释放元素值存储区 */
			if( son->ele.pAttr )
			{
				/* 删除所有属性值存储区 */
				for( i = 0; i < son->ele.AttrNum; i++ )
				{
					free( son->ele.pAttr[i].Name );/* 释放属性名存储区 */
					if( son->ele.pAttr[i].Value )
						free( son->ele.pAttr[i].Value );/* 释放元素值存储区 */
				}
				free( son->ele.pAttr );/* 释放属性列表存储区 */
			}
			
			/* 调整路径 */
			if( son != node )
			{
				if( son->parent )
					son->parent->son = son->next;
				if( son->next )
					son->next->prior = NULL;
				tmp = son->next ? son->next : son->parent;
				
				/* 删除结点 */
				free( son );
				
				/* 准备再次遍历(回溯) */
				son = tmp;
			}
			else
			{
				if( node->prior )
					node->prior->next = node->next;
				if( node->next )
					node->next->prior = node->prior;
				if( node->parent )
					node->parent->son = node->prior ? node->prior : node->next;
				else if( root->son == node )
					root->son = node->next;
								
				/* 删除结点 */
				free( node );
				
				/* 结束 */
				break;
			}
		}/* while( son ) */
	}
}

/* 函数功能: 在当前位置添加结点(兄弟或儿子) */
TREE_NODE* xmlTreeAdd( TREE_ROOT *root,
					   char      *key,
					   BOOL      bIsSon
					   )
{
	TREE_NODE *node, *new_node = NULL;
	

	if( root && key )
	{
		/* 分配新结点 */
		new_node = malloc( sizeof(TREE_NODE) );
		if( new_node )
		{
			/* 设备结点内容 */
			memset( new_node, 0, sizeof(TREE_NODE) );
			new_node->ele.Name = malloc( strlen(key) + 1 );
			if( new_node->ele.Name )
			{
				strcpy( new_node->ele.Name, key );
			
				node = root->cur ? root->cur : root->son;
				if( node )
				{
					if( root->cur && bIsSon )
					{
						/* 添加儿子 */
						if( !node->son )
						{
							node->son = new_node;
							new_node->parent = node;
							new_node->prior = NULL;
							node = NULL;
						}
						else
						{
							node = node->son;
						}
					}
					
					if( node )
					{
						/* 添加兄弟 */
						/* 将新结点链接至指定树枝上的未尾 */
						while( node->next )
						{
							node = node->next;
						}
						node->next = new_node;
						new_node->prior = node;
						new_node->parent = node->parent;
					}
				}
				else/* 空树 */
				{
					root->son = new_node;
					new_node->parent = NULL;
					new_node->prior = NULL;
				}
				
				/* 统计子结点个数 */
				if( new_node->parent )
					new_node->parent->sonNum++;
				else
					root->sonNum++;
				
				/* 设置当前结点位置 */
				root->cur = new_node;
			}
			else
			{
				free( new_node );
				
#if (XML_SHOW_DEBUG_INFO == TRUE)
				logMsg( "函数(xmlTreeAdd)返回失败, %s, %d\n", __FILE__, __LINE__ );
#endif
			}
		}
#if (XML_SHOW_DEBUG_INFO == TRUE)
		else
		{
			logMsg( "函数(xmlTreeAdd)返回失败, %s, %d\n", __FILE__, __LINE__ );
		}
#endif
	}
#if (XML_SHOW_DEBUG_INFO == TRUE)
	else
	{
		logMsg( "函数(xmlTreeAdd)返回失败, %s, %d\n", __FILE__, __LINE__ );
	}
#endif
	
	return new_node;
}

/* 函数功能: 插入结点 */
TREE_NODE* xmlTreeAddByPath( TREE_ROOT  *root,
				  	         char       *path,
				  	         char       *key,
				  	         BOOL       bIsSon
					         )
{
	TREE_NODE *node = NULL;
	
	
	if( root && key )
	{
		if( !path )
		{
			if( xmlTreeReach(root, path) )/* 定位插入点 */
			{
				node = xmlTreeAdd( root, key, bIsSon );
			}
#if (XML_SHOW_DEBUG_INFO == TRUE)
			else
			{
				logMsg( "函数(xmlTreeAddByPath)返回失败, %s, %d\n", __FILE__, __LINE__ );
			}
#endif
		}
		else
		{
			root->cur = NULL;
			node = xmlTreeAdd( root, key, bIsSon );
		}
	}
#if (XML_SHOW_DEBUG_INFO == TRUE)
	else
	{
		logMsg( "函数(xmlTreeAddByPath)返回失败, %s, %d\n", __FILE__, __LINE__ );
	}
#endif
	
	return node;
}

/* 函数功能: 删除当前结点 */
void xmlTreeDelete( TREE_ROOT  *root )
{
	if( root )
	{
		xmlTreeCut( root, root->cur );
	}
#if (XML_SHOW_DEBUG_INFO == TRUE)
	else
	{
		logMsg( "函数(xmlTreeDeleteCur)返回失败, %s, %d\n", __FILE__, __LINE__ );
	}
#endif
}

/* 函数功能: 删除指定结点 */
void xmlTreeDeleteByPath( TREE_ROOT  *root,
				          char       *path
				          )
{
	TREE_NODE *node;
	
	node = xmlTreeReach( root, path );/* 定位删除点 */
	if( node )
	{
		xmlTreeCut( root, node );
	}
#if (XML_SHOW_DEBUG_INFO == TRUE)
	else
	{
		logMsg( "函数(xmlTreeDelete)返回失败, %s, %d\n", __FILE__, __LINE__ );
	}
#endif
}

/* 函数功能: 定位于当前结点的右兄弟 */
TREE_NODE* xmlTreeMoveRight( TREE_ROOT *root )
{
	TREE_NODE *node = NULL;
	
	if( root )
	{
		if( root->cur )
		{
			node = root->cur->next;
			if( node )
			{
				/* 设置当前结点位置 */
				root->cur = node;
			}
		}
	}
	
	return node;
}

/* 函数功能: 定位于当前结点的左兄弟 */
TREE_NODE* xmlTreeMoveLeft( TREE_ROOT *root )
{
	TREE_NODE *node = NULL;
	
	if( root )
	{
		if( root->cur )
		{
			node = root->cur->prior;
			if( node )
			{
				/* 设置当前结点位置 */
				root->cur = node;
			}
		}
	}
	
	return node;
}

/* 函数功能: 定位于当前结点的父亲 */
TREE_NODE* xmlTreeMoveParent( TREE_ROOT *root )
{
	if( root )
	{
		if( root->cur )
		{
			root->cur = root->cur->parent;
		}
	}
	
	return root->cur;
}

/* 函数功能: 定位于当前结点的儿子 */
TREE_NODE* xmlTreeMoveSon( TREE_ROOT *root )
{
	TREE_NODE *node = NULL;
	
	if( root )
	{
		node = root->cur ? root->cur->son : root->son;
		if( node )
		{
			/* 设置当前结点位置 */
			root->cur = node;
		}
	}
	
	return node;
}

/* 函数功能: 获取当前结点 */
TREE_NODE* xmlTreeGetCur( TREE_ROOT *root )
{
	if( root )
		return root->cur;
	else
		return NULL;
}

/* 函数功能: 定位于根 */
void xmlTreeMoveRoot( TREE_ROOT *root )
{
	if( root )
		root->cur = NULL;
}

/* 函数功能: 检查同一层上的元素顺序(以当前元素为起点)
*  参数:
*  root[IN]:
*  order[IN]: 元素顺序, 格式为: dir_1>dir_2>[...]
*/
BOOL xmlTreeCheckOrder( TREE_ROOT  *root,
				 	    char       *order
				 	   )
{
	char      name[MAX_NAME_CHAR + 20];
	int       i, s1, s2;
	TREE_NODE *ele = NULL;
	
	
	if( root && order )
	{
		s1 = 0;
		s2 = strlen( order );
		ele = root->cur;
		
		while( ele && s1 < s2 )
		{
			/* 提取order中的元素名 */
			if( p_substr2(order + s1, 1, name, sizeof(name), '>') == 0 )
			{
				if( strcmp(ele->ele.Name, name) == 0 )
				{
					ele = ele->next;
					s1 += strlen( name ) + 1;
				}
				else
				{
					break;
				}
			}
		}/* while( ele && s1 < s2 ) */
	}
	
	return (s1 >= s2);
}

/************************************* 内部函数 *************************************/
/* 函数功能: 判断是否为XML有效字符(专用于检查标记名或属性名) */
BOOL xmlIsValidChar( UINT16 c )
{
	if( (c >= '0' && c <= '9') ||
		(c >= 'A' && c <= 'Z') ||
		(c >= 'a' && c <= 'z') ||
		(c == '_' || c == '-') 
		)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}

/* 函数功能: 判断是否为XML有效字符(专用于检查整个XML字符表达式) */
BOOL xmlIsValidCharEx( UINT16 c )
{
	if( (c >= '0' && c <= '9') ||
		(c >= 'A' && c <= 'Z') ||
		(c >= 'a' && c <= 'z') ||
		(c == '_' || c == '-' || c == ' ' || c == '\t' || c == '\r' || c == '\n') ||
		(c == '!' || c == ':' || c == '?' || c > 127)
		)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}

/* 函数功能: 将字串中的"\r"、"\n"、"\t"替换成" " */
void xmlReplaceChar( char *str, int str_len )
{
	int i;
	
	for( i = 0; i < str_len; i++ )
	{
		if( str[i] == '\r' ||
			str[i] == '\n' ||
			str[i] == '\t'
			)
		{
			str[i] = ' ';
		}
	}
}

/* 函数功能: 检查名称的有效性
*  参数:
*  name[IN]: 元素名或属性名
*  name_len[IN]: 
*  返回码: XML_ERROR, 请参见XML_ERROR的定义
*
*  名称必须符合以下几个条件:
*  1> 名称中可以包含字母、数字以及其它字母
*  2> 名称不能以数字或"-" 开头
*  3> 名称不能以字母 xml(或 XML 或 Xml ..)开头
*  4> 名称中不能包含空格
*  5> 名称中间不能包含":"(冒号)
*/
XML_ERROR xmlCheckName( const char *name, int name_len )
{

⌨️ 快捷键说明

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