📄 xmlanalyzer.c
字号:
{
if( version == 0 )
{
if( strcmp(node.TagName, "?xml") == 0 )/* XML声明 */
{
/* 读取属性version */
err = xmlGetAttrByName( exp, exp_len, "version", &attr );
if( err == XML_ERR_OK )
{
version = atof( attr.Value );
if( version > 1.0 )
err = XML_ERR_VERSION_UNSUPPORTED;
}
}
else
err = XML_ERR_DECLARE_INVALID;/* 在XML声明前不允许出现任何信息 */
}
else if( strcmp(node.TagName, "!--") == 0 )/* 注释 */
{
/* Do nothing */
}
else/* 用户TAG */
{
if( node.TagName[0] == '/' )/* 结束TAG </TAG> */
{
/* TAG出栈 */
if( xmlTagStack_Pop(&node2) )
{
/* 匹配TAG */
if( strcmp(&node.TagName[1], node2.TagName) != 0 )
{
err = XML_ERR_TAG_NOT_MATCH;
}
}
else
{
err = XML_ERR_ABSENCE_BEGIN_TAG;
}
}
else if( exp[exp_len - 2] == '/' )/* 空元素 */
{
/* Do nothing */
}
else/* 起始 <TAG> */
{
/* TAG入栈 */
if( !xmlTagStack_Push(&node) )
{
/* 嵌套级数溢出 */
err = XML_ERR_NEST_OVERFLOW;
}
}
}
if( err == XML_ERR_OK )
{
/* 调整字符缓冲区 */
txt_len -= ( exp_len + (exp - txt) );
memcpy( txt, exp + exp_len, txt_len );
}
}
}
}/* while( err == XML_ERR_OK ) */
fclose( hXML );/* 关闭XML文档 */
}
else
{
err = XML_ERR_FILE_NOT_EXIST;
}
semGive( XML_ANALYZER_LOCK );
}
else
{
err = XML_ERR_REJECT_REQUEST;
}
#if (XML_SHOW_DEBUG_INFO == TRUE)
if( err == XML_ERR_OK )
{
logMsg( "XML文档分析结果: 正确\n" );
}
else
{
logMsg( "XML文档分析结果: 错误\n错误表达式行数: %u\n错误信息: %s\n", XML_TEXT_LINE, xmlGetErrTxt(err) );
}
#endif
return err;
}
/* 函数功能: 载入XML文档
* 参数:
* fn[IN]:
* h[OUT]:
* 返回码:
*/
XML_ERROR xmlLoad( const char *fn, HXML *h )
{
FILE *hXML; /* XML文档句柄 */
char *exp; /* 单行XML表达式 */
char *val; /* 元素值 */
char txt[MAX_ELEMENT_EXPRESSION_CHAR + 1]; /* 文档字串 */
int txt_len; /* txt中的字符数 */
int exp_len; /* 由exp表示的表达式的字符数 */
int val_len; /* 元素值长度 */
int rds; /* 本次读取文件的字符数 */
int i, j; /* 中间变量 */
XML_STACK_NODE node, node2; /* TAG堆栈的结点 */
ATTRIBUTE_EX attr; /* TAG属性 */
TREE_ROOT *troot; /* XML树的根 */
TREE_NODE *tnode; /* XML树的结点 */
UINT32 fpos, fsize; /* XML文件当前指针、XML文件长度 */
XML_ERROR err; /* 错误码 */
err = xmlPreAnaylse( fn );/* 语法预分析 */
if( err == XML_ERR_OK )
{
if( semTake(XML_ANALYZER_LOCK, WAIT_FOREVER) == OK )
{
hXML = fopen( fn, "rb" );/* 打开XML文档 */
if( hXML )
{
/* 初始行号 */
XML_TEXT_LINE = 1;
/* 获取文件长度 */
fseek( hXML, 0, SEEK_END );
fsize = ftell( hXML );
fseek( hXML, 0, SEEK_SET );
/* 创建XML树 */
troot = xmlTreeBuild();
if( troot )
{
txt_len = 0;
fpos = 0;
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 )
break;
if( node.TagName[0] != '?' && node.TagName[0] != '!' )/* 用户TAG */
{
if( node.TagName[0] == '/' )/* 结束TAG </TAG> */
{
if( exp > txt )
{
/* 查看是否存在元素值(非' '字符串) */
for( i = (int)(exp - txt) - 1; i >= 0 ; i-- )
{
if( txt[i] != ' ' && txt[i] != '\r' &&
txt[i] != '\n' && txt[i] != '\t' )
{
for( j = 0; j < i; j++ )
{
if( txt[j] != ' ' && txt[j] != '\r' &&
txt[j] != '\n' && txt[j] != '\t' )
break;
}
/* 获取当前XML结点 */
tnode = xmlTreeGetCur( troot );
/* 提取元素值(以'\0'结尾的字符串) */
tnode->ele.Value = malloc( i - j + 2 );/* 分配元素值存储区 */
if( tnode->ele.Value )
{
memcpy( tnode->ele.Value, txt + j, i - j + 1 );
tnode->ele.Value[i - j + 1] = '\0';
}
else
{
err = XML_ERR_BUILD_TREE_FAIL;
}
break;
}
}/* for( i ) */
}
/* 插入点回溯至父结点 */
xmlTreeMoveParent( troot );
/* TAG出栈 */
if( !xmlTagStack_Pop(&node2) )
{
err = XML_ERR_ABSENCE_BEGIN_TAG;
}
}
else
{
/* 添加结点 */
tnode = xmlTreeAdd( troot, node.TagName, TRUE );
if( tnode )
{
#if( XML_DEBUG == TRUE )
/* 记录文本行号 */
tnode->ele.Line = XML_TEXT_LINE;
#endif
if( node.AttrNum > 0 )
{
/* 创建属性列表 */
tnode->ele.pAttr = malloc( sizeof(XML_ATTRIBUTE) * node.AttrNum );
if( tnode->ele.pAttr )
{
memset( tnode->ele.pAttr, 0, sizeof(XML_ATTRIBUTE) * node.AttrNum );/* 初始化属性表 */
tnode->ele.AttrNum = node.AttrNum;
/* 设置表中的每个属性 */
for( i = 0; i < node.AttrNum; i++ )
{
/* 提取指定属性 */
xmlGetAttrByNumber( exp, exp_len, i + 1, &attr );
/* 分配属性值存储区 */
tnode->ele.pAttr[i].Name = malloc( strlen(attr.Name) + 1 );
if( tnode->ele.pAttr[i].Name )
{
/* 复制属性 */
strcpy( tnode->ele.pAttr[i].Name, attr.Name );
if( attr.Value[0] != '\0' )
{
tnode->ele.pAttr[i].Value = malloc( strlen(attr.Value) + 1 );/* 分配属性值存储区 */
if( tnode->ele.pAttr[i].Value )
{
strcpy( tnode->ele.pAttr[i].Value, attr.Value );
}
else
{
err = XML_ERR_BUILD_TREE_FAIL;
break;
}
}
}
else
{
err = XML_ERR_BUILD_TREE_FAIL;
break;
}
}/* for( i ) */
}
else
{
err = XML_ERR_BUILD_TREE_FAIL;
}
}
}
else
{
err = XML_ERR_BUILD_TREE_FAIL;
}
if( err == XML_ERR_OK )
{
if( exp[exp_len - 2] != '/' )/* 只有非空元素才入栈 */
{
/* TAG入栈 */
if( !xmlTagStack_Push(&node) )
{
/* 嵌套级数溢出 */
err = XML_ERR_NEST_OVERFLOW;
}
}
else
{
/* 插入点回溯至父结点 */
xmlTreeMoveParent( troot );
}
}
}
}
if( err == XML_ERR_OK )
{
/* 调整字符缓冲区 */
txt_len -= ( exp_len + (exp - txt) );
memcpy( txt, exp + exp_len, txt_len );
}
}
}/* while( err == XML_ERR_OK ) */
if( err != XML_ERR_OK )
{
xmlTreeRelease( troot );
}
}
else
{
err = XML_ERR_BUILD_TREE_FAIL;
}
fclose( hXML );/* 关闭XML文档 */
}
else
{
err = XML_ERR_FILE_NOT_EXIST;
}
semGive( XML_ANALYZER_LOCK );
}
else
{
err = XML_ERR_REJECT_REQUEST;;
}
}
(*h) = err == XML_ERR_OK ? (HXML)troot : NULL;
return err;
}
/* 函数功能: 卸载XML文档
* 参数:
* h[IN]:
* 返回码:
*/
void xmlUnload( HXML h )
{
xmlTreeRelease( (TREE_ROOT*)h );
}
/* 函数功能: 读取指定路径下的子元素个数
* 参数:
* h[IN]:
* path[IN]:
* 返回码:
*/
UINT32 xmlGetSubEleNum( HXML h, char *path, char *name )
{
UINT32 n = 0;
TREE_NODE *node;
if( h )
{
if( !name )
{
if( path )
{
node = xmlTreeReach( (TREE_ROOT*)h, path );
if( node )
n = node->sonNum;
}
else
n = ( (TREE_ROOT*)h )->sonNum;
}
else
{
if( path )
{
node = xmlTreeReach( (TREE_ROOT*)h, path );
if( node )
node = node->son;
}
else
{
node = ( (TREE_ROOT*)h )->son;
}
while( node )
{
if( strcmp(node->ele.Name, name) == 0 )
n++;
node = node->next;
}
}
}
return n;
}
/* 函数功能: 读取当前元素的子元素的个数
* 参数:
* h[IN]:
* path[IN]:
* 返回码:
*/
UINT32 xmlGetCurSubEleNum( HXML h, char *name )
{
UINT32 n = 0;
TREE_NODE *node;
if( h )
{
node = xmlTreeGetCur( (TREE_ROOT*)h );
if( node && !name )
{
n = node->sonNum;
}
else if( node )
{
node = node->son;
while( node )
{
if( strcmp(node->ele.Name, name) == 0 )
n++;
node = node->next;
}
}
}
return n;
}
/* 函数功能: 测试是否存在指定元素
* 参数:
* h[IN]:
* path[IN]:
* 返回码:
*/
BOOL xmlIsExist( HXML h, char *path )
{
return xmlTreeReach( (TREE_ROOT*)h, path ) != NULL;
}
/* 函数功能: 读取指定元素 */
XML_ELEMENT* xmlGetElement( HXML h, char *path )
{
TREE_NODE *node;
node = xmlTreeReach( (TREE_ROOT*)h, path );
if( node )
return &node->ele;
else
return NULL;
}
/* 函数功能: 读取同级的下一个元素 */
XML_ELEMENT* xmlGetNextElement( HXML h )
{
TREE_NODE *node;
node = xmlTreeMoveRight( (TREE_ROOT*)h );
if( node )
return &node->ele;
else
return NULL;
}
/* 函数功能: 读取同级的前一个元素 */
XML_ELEMENT* xmlGetPriorElement( HXML h )
{
TREE_NODE *node;
node = xmlTreeMoveLeft( (TREE_ROOT*)h );
if( node )
return &node->ele;
else
return NULL;
}
/* 函数功能: 读取父级元素 */
XML_ELEMENT* xmlGetParentElement( HXML h )
{
TREE_NODE *node;
node = xmlTreeMoveParent( (TREE_ROOT*)h );
if( node )
return &node->ele;
else
return NULL;
}
/* 函数功能: 读取子级第一个元素 */
XML_ELEMENT* xmlGetSonElement( HXML h )
{
TREE_NODE *node;
node = xmlTreeMoveSon( (TREE_ROOT*)h );
if( node )
return &node->ele;
else
return NULL;
}
/* 函数功能: 读取当前元素 */
XML_ELEMENT* xmlGetCurrElement( HXML h )
{
TREE_NODE *node;
node = xmlTreeGetCur( (TREE_ROOT*)h );
if( node )
return &node->ele;
else
return NULL;
}
/* 函数功能: 读取指定元素的指定属性 */
XML_ATTRIBUTE* xmlGetAttr( HXML h, char *path, char *attr_name )
{
int i;
TREE_NODE *node;
XML_ATTRIBUTE *at = NULL;
if( h && path && attr_name )
{
node = xmlTreeReach( (TREE_ROOT*)h, path );
if( node )
{
for( i = 0; i < node->ele.AttrNum; i++ )
{
if( strcmp(node->ele.pAttr[i].Name, attr_name) == 0 )
{
at = &node->ele.pAttr[i];
break;
}
}
}
}
return at;
}
/* 函数功能: 读取当前元素的指定属性 */
XML_ATTRIBUTE* xmlGetCurrAttr( HXML h, char *attr_name )
{
int i;
TREE_NODE *node;
XML_ATTRIBUTE *at = NULL;
if( h && attr_name )
{
node = xmlTreeGetCur( (TREE_ROOT*)h );
if( node )
{
for( i = 0; i < node->ele.AttrNum; i++ )
{
if( strcmp(node->ele.pAttr[i].Name, attr_name) == 0 )
{
at = &node->ele.pAttr[i];
break;
}
}
}
}
return at;
}
/* 函数功能: 定位于根 */
void xmlMoveToRoot( HXML h )
{
xmlTreeMoveRoot( (TREE_ROOT*)h );
}
/* 函数功能: 将XML内部影像保存至外部文件 */
XML_ERROR xmlSave( HXML h )
{
return XML_ERR_REJECT_REQUEST;
}
/* 函数功能: 获取相关错误的中文描述
* 参数:
* errcode[IN]: 错误码
* 返回码: 如果匹配成功则返回一字符串, 否则返回NULL
*/
char* xmlGetErrTxt( XML_ERROR errcode )
{
switch( errcode )
{
case XML_ERR_OK:
return XML_ERRTXT_OK;
case XML_ERR_FILE_NOT_EXIST:
return XML_ERRTXT_FILE_NOT_EXIST;
case XML_ERR_DECLARE_INVALID:
return XML_ERRTXT_DECLARE_INVALID;
case XML_ERR_VERSION_UNSUPPORTED:
return XML_ERRTXT_VERSION_UNSUPPORTED;
case XML_ERR_ELEMENT_OVERFLOW:
return XML_ERRTXT_ELEMENT_OVERFLOW;
case XML_ERR_ELEMENT_NOT_EXIST:
return XML_ERRTXT_ELEMENT_NOT_EXIST;
case XML_ERR_ATTRIBUTE_OVERFLOW:
return XML_ERRTXT_ATTRIBUTE_OVERFLOW;
case XML_ERR_ATTRIBUTE_NOT_EXIST:
return XML_ERRTXT_ATTRIBUTE_NOT_EXIST;
case XML_ERR_NAME_TOO_LONG:
return XML_ERRTXT_NAME_TOO_LONG;
case XML_ERR_NAME_INVALID:
return XML_ERRTXT_NAME_INVALID;
case XML_ERR_EXPRESSION_INVALID:
return XML_ERRTXT_EXPRESSION_INVALID;
case XML_ERR_AT_VALUE_TOO_LONG:
return XML_ERRTXT_AT_VALUE_TOO_LONG;
case XML_ERR_ELE_VALUE_TOO_LONG:
return XML_ERRTXT_ELE_VALUE_TOO_LONG;
case XML_ERR_FILE_IO:
return XML_ERRTXT_FILE_IO;
case XML_ERR_EXPRESSION_NULL:
return XML_ERRTXT_EXPRESSION_NULL;
case XML_ERR_UNDEFINED_KEY:
return XML_ERRTXT_UNDEFINED_KEY;
case XML_ERR_UNSUPPORTED_KEY:
return XML_ERRTXT_UNSUPPORTED_KEY;
case XML_ERR_DATA_EMPTY:
return XML_ERRTXT_DATA_EMPTY;
case XML_ERR_NEST_OVERFLOW:
return XML_ERRTXT_NEST_OVERFLOW;
case XML_ERR_TAG_NOT_MATCH:
return XML_ERRTXT_TAG_NOT_MATCH;
case XML_ERR_REJECT_REQUEST:
return XML_ERRTXT_REJECT_REQUEST;
case XML_ERR_BUILD_TREE_FAIL:
return XML_ERRTXT_BUILD_TREE_FAIL;
case XML_ERR_PARAM_INVALID:
return XML_ERRTXT_PARAM_INVALID;
default:
return NULL;
}
}
#if (XML_DEBUG == TRUE)
/* 调试函数 */
void xmlDebug( char *fn )
{
HXML h;
XML_ELEMENT *ele;
XML_ATTRIBUTE *attr;
char path[1000];
xmlInitiate(); /* 初始化XML分析器 */
xmlLoad( fn, &h ); /* 加载XML文档 */
#if 0
/* 搜索结点 */
xmlMoveToRoot( h );
printf( "XML树共有%d棵子树组成\n", xmlGetSubEleNum(h, NULL, NULL) );
sprintf( path, "SERVER.SAP" );
ele = xmlGetElement( h, path );
sprintf( path, "SERVER.LD.LN[3].FC.DT" );
ele = xmlGetElement( h, path );
#endif
xmlUnload( h ); /* 卸载XML影像 */
xmlRelease(); /* 关闭XML分析器 */
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -