/* Copyright (c) 2005 wzs */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <varargs.h>
#include "xmlparse.h"
/*xml得到节点名值, 返回: 1节点标识名开头, 2节点标识名结尾, 3 注释 , 4元素数据 <=0有错误 */
#define XVAL_NBEGIN 1
#define XVAL_NEND 2
#define XVAL_NOTE 3
#define XVAL_DATA 4
#define XVAL_TAG 5 /* 空标志 */
#define XVAL_NONE 0
#define XVAL_ERROR -1
static int isSpace(int c) /* 是空否 */
{
switch (c) {
case 0x20:
case 0xD:
case 0xA:
case 0x9:
return 1;
}
return 0;
}
static int isNameTChar(int c) /* 有效的名称前导符 */
{
return (c>='A' && c<='Z') || (c>='a' && c<='z') || (c=='_') ;
}
int EqXString (XSTRING *dxs, XSTRING *sxs ) /* X字串赋值 */
{
dxs->text = sxs->text ;
dxs->len = sxs->len ;
return 0;
}
int EqXNode (XNODE *dx, XNODE *sx ) /* X节点赋值 */
{
EqXString ( &(dx->name), &(sx->name) );
dx->index = sx->index ;
dx->parentNode = sx->parentNode ;
dx->level = sx->level ;
dx->tagCount = sx->tagCount ;
EqXString ( &(dx->data), &(sx->data) );
return 0;
}
/* 增加同级节点: */
XNODE *XAddNode(XTREE *xTree , XSTRING *name)
{
if (xTree->curNode->parentNode == NULL || xTree->nodeCount >= xTree->nodeMaxCount ) return NULL ;
(xTree->nodeCount) ++ ;
xTree->preNode = xTree->curNode ;
xTree->curNode = & (xTree->nodeList[ xTree->nodeCount -1 ] ) ;
xTree->curNode->index = xTree->nodeCount -1 ;
EqXString (&(xTree->curNode->name), name);
xTree->curNode->parentNode = xTree->preNode->parentNode ;
xTree->curNode->level = xTree->preNode->level ;
(xTree->curNode->parentNode->tagCount) ++ ;
return (xTree->curNode);
}
/* 增加子节点: */
XNODE *XAddSubNode(XTREE *xTree , XSTRING *name)
{
if (xTree->curNode == NULL || xTree->nodeCount >= xTree->nodeMaxCount ) return NULL ;
(xTree->nodeCount) ++ ;
xTree->preNode = xTree->curNode ;
xTree->curNode = & (xTree->nodeList[ xTree->nodeCount -1 ]) ;
xTree->curNode->index = xTree->nodeCount -1 ;
EqXString (&(xTree->curNode->name), name);
xTree->curNode->parentNode = xTree->preNode ;
xTree->curNode->level = xTree->preNode->level +1 ;
(xTree->preNode->tagCount) ++ ;
return (xTree->curNode);
}
/* 返回父节点: */
XNODE *XRetParentNode(XTREE *xTree )
{
if (xTree->curNode->parentNode == NULL ) return NULL;
xTree->preNode = xTree->curNode ;
xTree->curNode = xTree->curNode->parentNode ;
return (xTree->curNode);
}
/* 修改当前节点元素值: */
int XElementData(XTREE *xTree , XSTRING *data)
{
if (xTree->curNode == NULL ) return -1 ;
/* if (xTree->curNode->tagCount>0) return -2; */
EqXString ( &(xTree->curNode->data), data) ;
return 0;
}
char *DelSpace( char *xbuf) /* 删除前导空 */
{
char *p ;
for (p=xbuf ; isSpace(*p) ; p++); /* 去掉空字符 */
return (p);
}
int XmlAttr( XTREE *xTree, XSTRING *val) /* 处理属性: 当作叶节点, 子节点数为-1, 返回增加的属性节点数 */
{
XSTRING xn, xv;
int k=0;
char *p1, *p, *p2;
p=DelSpace(val->text);
while (p && *p) {
p1= p ;
p2=strchr(p1, '=');
if (p2==NULL) break ;
xn.text = p1 ;
*p2='/0';
xn.len = p2- p1 ;
p=DelSpace(p2+1);
if (*p !='"') break ;
p1= p ;
p2=strchr(p1+1, '"');
if (p2==NULL) break ;
xv.text = p1+1;
*p2 ='/0';
xv.len = p2-p1-1;
/* 增加属性值节点 */
if (XAddSubNode(xTree, &xn)==NULL) break ;
k++;
if (XElementData(xTree , &xv) <0 ) break ;
xTree->curNode->tagCount = -1;
XRetParentNode( xTree ) ;
p=DelSpace(p2+1);
}
return (k);
}
/* xml得到节点名值, 返回: 1节点标识名开头, 2节点标识名结尾, 3 注释 , 4元素数据 0无 -1有错误 */
int XmlReadNodeVal(XTREE *xTree, XSTRING *val )
{
char *p ,*p1, *p2;
int ivtype=XVAL_NONE ;
p=xTree->xBufPos ;
p=DelSpace( xTree->xBufPos) ; /* 删除前导空 */
if (*p !='<') { /* 数据 */
p1 = p;
p2=strchr(p1, '<');
val->text = p1;
val->len = ( p2 ? p2-p1 : 0);
ivtype = ( p2 && p2 < xTree->xBufEnd ? XVAL_DATA : XVAL_NONE) ;
xTree->xBufPos = (p2 ? p2 : xTree->xBufEnd);
goto OKExit33qqq ;
}
/* 前导为< */
p++;
if ( *p=='/' ) { /* 标记尾 */
p1 = p+1;
p2=strchr(p1, '>');
if (p2==NULL) { /* 错误 */
goto ErrExit33qqq ;
} else {
ivtype=XVAL_NEND;
val->text = p1;
val->len = p2-p1;
xTree->xBufPos = p2 +1 ;
}
}
else if (isNameTChar(*p)) { /* 标记头 */
p1=p;
p2=strchr(p1,'>');
if (p2==NULL) { /* 错误 */
goto ErrExit33qqq ;
}
for (p=p1; *p!=' ' && p<p2; p++);
if (*(p2-1)=='/') { /* 处理空标记<abc/> */
ivtype=11;
val->text = p1;
if (p>=p2) p=p2-1;
val->len = p - p1;
if ( XAddSubNode( xTree , val ) == NULL) goto ErrExit33qqq ;
if (p < p2-1 ) /* 增加属性节点 */
{
*(p2-1) ='/0';
p++;
val->text = p ;
val->len = p2-1- p;
ivtype += XmlAttr(xTree, val );
}
XRetParentNode( xTree ) ;
} else {
ivtype=XVAL_NBEGIN;
val->text = p1;
val->len = p - p1;
if (p < p2) /* 增加属性节点 */
{
if ( XAddSubNode( xTree , val ) == NULL) goto ErrExit33qqq ;
*(p2) ='/0';
p++;
val->text = p ;
val->len = p2 - p;
ivtype = 11+ XmlAttr(xTree, val );
}
}
xTree->xBufPos = p2 +1 ;
}
else if (*p=='!') {
if (*(p+1)=='-' && *(p+2)=='-') /* 注释 */
{
p+=3;
p1=DelSpace(p);
p2=strstr(p1, "-->"); /*注释尾 */
if (p2==NULL) { /* 错误 */
goto ErrExit33qqq ;
} else {
ivtype=XVAL_NOTE;
xTree->xBufPos = p2+3;
val->text = p1;
val->len = (p2 - p1) / sizeof(char) ;
}
goto OKExit33qqq ;
}
}
OKExit33qqq:
return (ivtype) ;
ErrExit33qqq :
ivtype=XVAL_ERROR;
xTree->xBufPos = xTree->xBufEnd ;
return (ivtype) ;
}
/* 读xml并解析到X树 */
int XmlParseRead(char *xmlbuf, int xmlsize, XTREE *xTree)
{
char *p, *p1, *pend = xmlbuf + xmlsize;
XSTRING xstr ;
XNODE *xn ;
register int k;
int maxnn=0, vtype=XVAL_NONE, vtype0=XVAL_NONE ;
memset( xTree, 0x00, sizeof(XTREE) );
if (memcmp(xmlbuf,"<?xml version=", 14)!=0)
{
XPrtErr("无XML内容头!");
return -1;
}
p=strstr(xmlbuf, "?>") ;
if (p==NULL)
{
XPrtErr("XML内容头无结尾!");
return -1;
}
p1=DelSpace(p+2);
for (p=p1, maxnn=1; p<pend ; p++) {
if (*p=='>' || *p=='"') maxnn++;
if (*p=='>') if (*(p-1) == '/') maxnn++; /* 空标记 */
}
maxnn = maxnn / 2 + 2 ;
xTree->xBuf =xmlbuf;