📄 xmlanalyzer.c
字号:
#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 + -