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

📄 xmlanalyzer.c

📁 基于Vxworks平台的几个代码(C)
💻 C
📖 第 1 页 / 共 3 页
字号:
	int    i;
	char   tmp[4];
	XML_ERROR err = XML_ERR_NAME_INVALID;
	
	if( name_len > 0 )
	{
		if( name_len > MAX_NAME_CHAR )
		{
			err = XML_ERR_NAME_TOO_LONG;
		}
		else if( !(name[0] == '-' || name[0] == ' ' || (name[0] >= '0' && name[0] <= '9')) )
		{
			if( name_len >= 3 )
			{
				strncpy( tmp, name, 3 );
				tmp[3] = '\0';
				p_toupper( tmp );
				
				if( strcmp(tmp, "XML") != 0 )
				{
					err = XML_ERR_OK;
				}
			}
			else
			{
				err = XML_ERR_OK;
			}
			
			if( err == XML_ERR_OK )
			{
				for( i = 0; i < name_len; i++ )
				{
					if( !xmlIsValidChar((UINT16)name[i]) )
					{
						err = XML_ERR_NAME_INVALID;
						break;
					}
				}
			}
		}
	}
	
	return err;
}

/* 函数功能: 从一行XML表达式中获取第n个属性
*  参数:
*  exp[IN]: XML表达式
*  number[IN]: 属性编号
*  attr[OUT]: 用于存放属性
*  返回码:
*
*  注: 在调用该函数前必须先调用xmlAnaylseExpression
*/
XML_ERROR xmlGetAttrByNumber( const char *exp, int exp_len, int number, ATTRIBUTE_EX *attr )
{
	int  i, j, i2, j2, n;
	XML_ERROR err = XML_ERR_ATTRIBUTE_NOT_EXIST;
	
	
	if( exp[exp_len - 2] == '/' || exp[exp_len - 2] == '?')
		exp_len -= 2;
		
	i = 2;
	n = number;
	while( n > 0 )
	{
		/* 搜索分隔符' ' */
		for( i; i < exp_len; i++ )
		{
			if( exp[i - 1] == ' ' && exp[i] != ' ' )
				break;
		}/* for( i ) */
		
		if( i >= exp_len )
		{
			err = XML_ERR_ATTRIBUTE_NOT_EXIST;
			break;
		}
		else
		{
			err = XML_ERR_EXPRESSION_INVALID;
			
			/* 搜索字符'=' */
			for( j = i + 1; j < exp_len; j++ )
			{
				if( exp[j] == '=')
				{
					/* 检查属性名 */
					err = xmlCheckName( &exp[i], j - i );
					break;
				}
				else if( !xmlIsValidChar(exp[j]) )
				{	
					break;
				}
			}/* for( j ) */
			
			if( err == XML_ERR_OK )
			{
				err = XML_ERR_EXPRESSION_INVALID;
				
				/* 检查属性值 */
				for( i2 = j + 1; i2 < exp_len; i2++ )
				{
					if( exp[i2] == '\"' || exp[i2] == '\'' )
					{
						for( j2 = i2 + 1; j2 < exp_len; j2++ )
						{
							if( exp[j2] == '\"' || exp[j2] == '\'' )
								break;
						}
						
						if( j2 < exp_len )
						{
							if( j2 - i2 - 1 <= MAX_AT_VALUE_CHAR )
								err = XML_ERR_OK;
							else
								err = XML_ERR_AT_VALUE_TOO_LONG;
						}
						break;
					}
					else if( exp[i2] != ' ' )
					{
						break;
					}
				}/* for( i2 ) */
			}
		}
		
		if( err == XML_ERR_OK )
		{
			if( (--n) == 0 )
			{
				/* 复制属性名 */
				strncpy( attr->Name, &exp[i], j - i );
				attr->Name[j - i] = '\0';
				
				/* 复制属性值 */
				strncpy( attr->Value, &exp[i2 + 1], j2 - i2 - 1 );
				attr->Value[j2 - i2 - 1] = '\0';
				
				break;
			}
			else
			{
				i = j2 + 1;/* 下一个属性的起始位置 */
			}
		}
		else
		{
			break;
		}
	}/* while( n ) */
	
	return err;
}

/* 函数功能: 从一行XML表达式中获取指定属性名的属性
*  参数:
*  exp[IN]: XML表达式
*  name[IN]: 属性名
*  attr[OUT]: 用于存放属性
*  返回码:
*/
XML_ERROR xmlGetAttrByName( const char *exp, int exp_len, const char *name, ATTRIBUTE_EX *attr )
{
	int  i, j, i2, j2, n;
	XML_ERROR err = XML_ERR_ATTRIBUTE_NOT_EXIST;
	
	
	if( exp[exp_len - 2] == '/' || exp[exp_len - 2] == '?')
		exp_len -= 2;
		
	i = 2;
	while( TRUE )
	{
		/* 搜索分隔符' ' */
		for( i; i < exp_len; i++ )
		{
			if( exp[i - 1] == ' ' && exp[i] != ' ' )
				break;
		}/* for( i ) */
		
		if( i >= exp_len )
		{
			err = XML_ERR_ATTRIBUTE_NOT_EXIST;
			break;
		}
		else
		{
			err = XML_ERR_EXPRESSION_INVALID;
			
			/* 搜索字符'=' */
			for( j = i + 1; j < exp_len; j++ )
			{
				if( exp[j] == '=')
				{
					/* 检查属性名 */
					err = xmlCheckName( &exp[i], j - i );
					break;
				}
				else if( !xmlIsValidChar(exp[j]) )
				{	
					break;
				}
			}/* for( j ) */
			
			if( err == XML_ERR_OK )
			{
				err = XML_ERR_EXPRESSION_INVALID;
				
				/* 检查属性值 */
				for( i2 = j + 1; i2 < exp_len; i2++ )
				{
					if( exp[i2] == '\"' || exp[i2] == '\'' )
					{
						for( j2 = i2 + 1; j2 < exp_len; j2++ )
						{
							if( exp[j2] == '\"' || exp[j2] == '\'' )
								break;
						}
						
						if( j2 < exp_len )
						{
							if( j2 - i2 - 1 <= MAX_AT_VALUE_CHAR )
								err = XML_ERR_OK;
							else
								err = XML_ERR_AT_VALUE_TOO_LONG;
						}
						break;
					}
					else if( exp[i2] != ' ' )
					{
						break;
					}
				}/* for( i2 ) */
			}
		}
		
		if( err == XML_ERR_OK )
		{
			/* 复制属性名 */
			strncpy( attr->Name, &exp[i], j - i );
			attr->Name[j - i] = '\0';
			if( strcmp(name, attr->Name) == 0 )
			{
				/* 复制属性值 */
				strncpy( attr->Value, &exp[i2 + 1], j2 - i2 - 1 );
				attr->Value[j2 - i2 - 1] = '\0';
				
				break;
			}
			else
			{
				i = j2 + 1;/* 下一个属性的起始位置 */
			}
		}
		else
		{
			break;
		}
	}/* while( TRUE ) */
	
	return err;
}

/* 函数功能: 统计一行XML表达式中的属性个数
*  参数:
*  返回码:
*  成功则返回属性个数, 否则返回XML_ERROR
*/
int xmlGetAttrNumber( const char *exp, int exp_len )
{
	int  i, j, i2, j2, n;
	XML_ERROR err = XML_ERR_ATTRIBUTE_NOT_EXIST;
	
	
	if( exp[exp_len - 2] == '/' || exp[exp_len - 2] == '?')
		exp_len -= 2;
		
	i = 2;
	n = 0;
	while( TRUE )
	{
		/* 搜索分隔符' ' */
		for( i; i < exp_len; i++ )
		{
			if( exp[i - 1] == ' ' && exp[i] != ' ' )
				break;
		}/* for( i ) */
		
		if( i >= exp_len )
		{
			err = XML_ERR_OK;
			break;
		}
		else
		{
			err = XML_ERR_EXPRESSION_INVALID;
			
			/* 搜索字符'=' */
			for( j = i + 1; j < exp_len; j++ )
			{
				if( exp[j] == '=')
				{
					/* 检查属性名 */
					err = xmlCheckName( &exp[i], j - i );
					break;
				}
				else if( !xmlIsValidChar(exp[j]) )
				{	
					break;
				}
			}/* for( j ) */
			
			if( err == XML_ERR_OK )
			{
				err = XML_ERR_EXPRESSION_INVALID;
				
				/* 检查属性值 */
				for( i2 = j + 1; i2 < exp_len; i2++ )
				{
					if( exp[i2] == '\"' || exp[i2] == '\'' )
					{
						for( j2 = i2 + 1; j2 < exp_len; j2++ )
						{
							if( exp[j2] == '\"' || exp[j2] == '\'' )
								break;
						}
						
						if( j2 < exp_len )
						{
							if( j2 - i2 - 1 <= MAX_AT_VALUE_CHAR )
								err = XML_ERR_OK;
							else
								err = XML_ERR_AT_VALUE_TOO_LONG;
						}
						break;
					}
					else if( exp[i2] != ' ' )
					{
						break;
					}
				}/* for( i2 ) */
			}
		}
		
		if( err == XML_ERR_OK )
		{
			n++;
			i = j2 + 1;/* 下一个属性的起始位置 */
		}
		else
		{
			break;
		}
	}/* while( TRUE ) */
	
	return err == XML_ERR_OK ? n : err;
}

/* 函数功能: 从一字符集中提取一个以<>限定的XML表达式
*  参数:
*  返回码:
*/
XML_ERROR xmlGetExpression( char *str, int str_size, char **exp, int *exp_len )
{
	int       i, j;
	XML_ERROR err = XML_ERR_EXPRESSION_NULL;
	
	
	(*exp) = NULL;
	(*exp_len) = 0;
	
	/* 搜索字符'<' */
	for( i = 0; i < str_size; i++ )
	{
		if( str[i] == '<' )
		{
			/* 搜索字符'>' */
			for( j = i + 1; j < str_size; j++ )
			{
				if( str[j] == '>' )
				{
					(*exp) = str + i;
					(*exp_len) = j - i + 1;
					
					err = XML_ERR_OK;
					break;
				}
			}
			
			if( j == str_size )
				err = XML_ERR_EXPRESSION_INVALID;
			break;
		}
		else if( str[i] == '\n' )
		{
			XML_TEXT_LINE++;
		}
#if 0
		else if( str[i] != ' ' && str[i] != '\t' && str[i] != '\r' && str[i] != '\n' )
		{
			/* 限定在字符'<'前只能出现' '、'\t'、'\r'、'\n', 四种字符 */
			err = XML_ERR_EXPRESSION_INVALID;
			break;
		}
#endif
	}
	
	if( i == str_size )
	{
		if( str_size == 2 && str[0] == '\r' && str[1] == '\n' )
			err = XML_ERR_OK;/* 表示最后一行为空行 */
		else
			err = XML_ERR_ELE_VALUE_TOO_LONG;
	}
	
	return err;
}

/* 函数功能: 分析单行XML表达式
*  参数:
*  返回码:
*  
*  <TAG>, <!>, <?>
*/
XML_ERROR xmlAnaylseExpression( char *exp, int exp_len, char *tag_name, int *attr_num )
{
	int          i, j;
	ATTRIBUTE_EX attr;
	XML_ERROR    err = XML_ERR_EXPRESSION_INVALID;
	
	/* 将表达式中的一些字符替换成空格 */
	xmlReplaceChar( exp, exp_len );

	if( exp_len >= 3 )
	{
		if( (exp[1] >= 'a' && exp[1] <= 'z') ||
			(exp[1] >= 'A' && exp[1] <= 'Z')
			)
		{
			/* 普通TAG */
			for( i = 2; i < exp_len; i++ )
			{
				if( exp[i] == ' ' || exp[i] == '>' )
				{
					if( exp[i] == ' ' )
					{
						/* 如果存在字符' '则其后必须存在其它有效字符 */
						for( j = i + 1; j < exp_len; j++ )
						{
							if( xmlIsValidChar(exp[j]) )
							{
								break;
							}
							else if( exp[j] != ' ' )
							{
								j = exp_len;
								break;
							}
						}
						
						if( j == exp_len )
						{
							err = XML_ERR_EXPRESSION_INVALID;
							i = exp_len;
						}
					}
					else if( exp[i - 1] == '/' && exp[i] == '>' )
					{
						i--;
					}
					
					if( i < exp_len )
					{
						err = xmlCheckName( &exp[1], i - 1 );
						if( err == XML_ERR_OK )
						{
							/* 复制TAG名 */
							strncpy( tag_name, &exp[1], i - 1 );
							tag_name[i - 1] = '\0';
							
							if( exp_len > i + 1 )
							{
								/* 获取属性个数 */
								(*attr_num) = xmlGetAttrNumber( exp, exp_len );
								if( (*attr_num) >= 0 )
									err = XML_ERR_OK;
								else
									err = XML_ERR_EXPRESSION_INVALID;
							}
							else
							{
								(*attr_num) = 0;
								err = XML_ERR_OK;
							}
						}
					}
					
					break;
				}
			}/* for */
		}
		else if( exp[1] == '/' )
		{
			err = xmlCheckName( &exp[2], exp_len - 3 );
			if( err == XML_ERR_OK )
			{
				(*attr_num) = 0;
				/* 复制TAG名 */
				strncpy( tag_name, &exp[1], exp_len - 2 );
				tag_name[exp_len - 2] = '\0';
			}
		}
		else
		{
			/* XML声明或定义 */
			
			switch( exp[1] )
			{
			case '?':	/* XML声明 */
				/* <?xml version="1.0" ?> */
				if( exp[exp_len - 2] == '?' && exp_len >= 20 )
				{
					if( exp[2] == 'x' && exp[3] == 'm' && exp[4] == 'l' && exp[5] == ' ' )
					{
						/* 复制TAG名 */
						strcpy( tag_name, "?xml" );
						/* 获取属性个数 */
						(*attr_num) = xmlGetAttrNumber( exp, exp_len );
						if( (*attr_num) > 0 )
							err = XML_ERR_OK;
						else
							err = XML_ERR_DECLARE_INVALID;
					}
				}
				break;
				
			case '!':	/* 注释或定义 */
				if( exp[2] == '-' )
				{
					/* 检查是否为注释<!--[...]--> */
					if( exp_len >= 7 )
					{
						if( exp[2] == '-' && exp[3] == '-' &&
							exp[exp_len - 3] == '-' && exp[exp_len - 2] == '-' )
						{
							strcpy( tag_name, "!--" );
							(*attr_num) = 0;
							err = XML_ERR_OK;
						}
					}
				}
				else
				{
					/* 定义(暂不支持) */
					err = XML_ERR_UNSUPPORTED_KEY;
				}
				break;
				
			default:	/* 无效 */
				break;
			}
		}
	}
#if 0
	else if( exp_len == 0 )
	{
		tag_name[0] = '\0';
		(*attr_num) = 0;
		err = XML_ERR_OK;
	}
#endif
		
	return err;
}


/************************************* 接口函数 *************************************/

/* 函数功能: 初始化XML分析器 */
BOOL xmlInitiate()
{
	BOOL ret = FALSE;
	
	if( !XML_ANALYZER_LOCK )
	{
		XML_ANALYZER_LOCK = semBCreate( SEM_Q_FIFO, SEM_FULL );
		if( XML_ANALYZER_LOCK )
			ret = TRUE;
	}
	
	return ret;
}

/* 函数功能: 关闭XML分析器 */
void xmlRelease()
{
	if( XML_ANALYZER_LOCK )
	{
		semDelete( XML_ANALYZER_LOCK );
		XML_ANALYZER_LOCK = NULL;
	}
}

/* 函数功能: XML语法预分析
*  参数:
*  返回码:
*  分析算法:
*  1>
*/
XML_ERROR xmlPreAnaylse( const char *fn )
{
	FILE       *hXML;					/* XML文档句柄 */
	char       *exp;					/* 单行XML表达式 */
	char       txt[MAX_ELEMENT_EXPRESSION_CHAR + 1];	/* 文档字串 */
	int        txt_len;					/* txt中的字符数 */
	int        exp_len;					/* 由exp表示的表达式的字符数 */
	int        rds;						/* 本次读取文件的字符数 */
	float      version;					/* 版本信息 */
	XML_STACK_NODE node, node2;			/* TAG堆栈的结点 */
	ATTRIBUTE_EX   attr;				/* TAG属性 */
	UINT32     fpos, fsize;				/* XML文件当前指针、XML文件长度 */
	XML_ERROR  err;						/* 错误码 */
	
	
	if( semTake(XML_ANALYZER_LOCK, WAIT_FOREVER) == OK )
	{
		hXML = fopen( fn, "rb" );/* 打开XML文档 */
		if( hXML )
		{	
			/* 获取文件长度 */
			fseek( hXML, 0, SEEK_END );
			fsize = ftell( hXML );
			fseek( hXML, 0, SEEK_SET );
			
			xmlTagStack_Init();	/* 初始化TAG堆栈 */
			XML_TEXT_LINE = 1;	/* 当前正在分析的文本行, 初始状态为1 */
			
			version = 0;
			txt_len = 0;
			fpos = 0;
			err = XML_ERR_OK;
			
			while( err == XML_ERR_OK )
			{
				if( fpos < fsize )
				{
					/* 读取文档内容 */
					rds = fread( txt + txt_len, 1, MAX_ELEMENT_EXPRESSION_CHAR - txt_len, hXML );
					if( rds > 0 )
					{
						txt_len += rds;
						fpos += rds;
					}
					else
					{
						err = XML_ERR_FILE_IO;
						break;
					}
				}
				else if( txt_len == 0 )
				{
					/* 分析结束 */
					if( !xmlTagStack_IsEmpty() )
					{
						err = XML_ERR_TAG_NOT_MATCH;
					}
					break;
				}
				
				if( txt_len == 0 )
				{
					err = XML_ERR_DATA_EMPTY;
					break;
				}
				
				/* 获取单行XML表达式 */
				err = xmlGetExpression( txt, txt_len, &exp, &exp_len );
				
				if( err == XML_ERR_OK )
				{
					/* 进行初步分析 */
					err = xmlAnaylseExpression( exp, exp_len, node.TagName, &node.AttrNum );
					if( err == XML_ERR_OK )

⌨️ 快捷键说明

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