📄 ixmlparser.c
字号:
( IXML_Node * ) newElement );
if( rc != IXML_SUCCESS ) {
ixmlElement_free( newElement );
return rc;
}
xmlParser->currentNodePtr = ( IXML_Node * ) newElement;
// push element to stack
rc = Parser_pushElement( xmlParser, ( IXML_Node * ) newElement );
return rc;
}
/*================================================================
* Parser_eTagVerification
* Verifies endof element tag is the same as the openning
* element tag.
* Internal to parser only.
*
*=================================================================*/
static int
Parser_eTagVerification( IN Parser * xmlParser,
IN IXML_Node * newNode )
{
assert( newNode->nodeName );
assert( xmlParser->currentNodePtr );
if( newNode->nodeType == eELEMENT_NODE ) {
if( Parser_isValidEndElement( xmlParser, newNode ) == TRUE ) {
Parser_popElement( xmlParser );
} else { // syntax error
return IXML_SYNTAX_ERR;
}
}
if( strcmp( newNode->nodeName, xmlParser->currentNodePtr->nodeName ) ==
0 ) {
xmlParser->currentNodePtr = xmlParser->currentNodePtr->parentNode;
} else {
return IXML_SYNTAX_ERR;
}
return IXML_SUCCESS;
}
/*================================================================
* Parser_freeNodeContent
* frees a node contents
* Internal to parser only.
*
*=================================================================*/
void
Parser_freeNodeContent( IN IXML_Node * nodeptr )
{
if( nodeptr == NULL ) {
return;
}
if( nodeptr->nodeName != NULL ) {
free( nodeptr->nodeName );
}
if( nodeptr->nodeValue != NULL ) {
free( nodeptr->nodeValue );
}
if( nodeptr->namespaceURI != NULL ) {
free( nodeptr->namespaceURI );
}
if( nodeptr->prefix != NULL ) {
free( nodeptr->prefix );
}
if( nodeptr->localName != NULL ) {
free( nodeptr->localName );
}
}
/*================================================================
* Parser_parseDocument
* Parses the xml file and returns the DOM document tree.
* External function.
*
*=================================================================*/
static int
Parser_parseDocument( OUT IXML_Document ** retDoc,
IN Parser * xmlParser )
{
IXML_Document *gRootDoc = NULL;
IXML_Node newNode;
BOOL bETag = FALSE;
IXML_Node *tempNode = NULL;
int rc = IXML_SUCCESS;
IXML_CDATASection *cdataSecNode = NULL;
ixmlNode_init( &newNode );
rc = ixmlDocument_createDocumentEx( &gRootDoc );
if( rc != IXML_SUCCESS ) {
goto ErrorHandler;
}
xmlParser->currentNodePtr = ( IXML_Node * ) gRootDoc;
rc = Parser_skipProlog( xmlParser );
if( rc != IXML_SUCCESS ) {
goto ErrorHandler;
}
while( bETag == FALSE ) {
// clear the newNode contents
ixmlNode_init( &newNode );
if( Parser_getNextNode( xmlParser, &newNode, &bETag ) ==
IXML_SUCCESS ) {
if( bETag == FALSE ) {
switch ( newNode.nodeType ) {
case eELEMENT_NODE:
rc = Parser_processElementName( gRootDoc,
xmlParser,
&newNode );
if( rc != IXML_SUCCESS ) {
goto ErrorHandler;
}
break;
case eTEXT_NODE:
rc = ixmlDocument_createTextNodeEx( gRootDoc,
newNode.
nodeValue,
&tempNode );
if( rc != IXML_SUCCESS ) {
goto ErrorHandler;
}
rc = ixmlNode_appendChild( xmlParser->
currentNodePtr,
tempNode );
if( rc != IXML_SUCCESS ) {
goto ErrorHandler;
}
break;
case eCDATA_SECTION_NODE:
rc = ixmlDocument_createCDATASectionEx( gRootDoc,
newNode.
nodeValue,
&cdataSecNode );
if( rc != IXML_SUCCESS ) {
goto ErrorHandler;
}
rc = ixmlNode_appendChild( xmlParser->
currentNodePtr,
&( cdataSecNode->n ) );
if( rc != IXML_SUCCESS ) {
goto ErrorHandler;
}
break;
case eATTRIBUTE_NODE:
rc = Parser_processAttributeName( gRootDoc,
xmlParser,
&newNode );
if( rc != IXML_SUCCESS ) {
goto ErrorHandler;
}
break;
default:
break;
}
} else // ETag==TRUE, endof element tag.
{
rc = Parser_eTagVerification( xmlParser, &newNode );
if( rc != IXML_SUCCESS ) {
goto ErrorHandler;
}
xmlParser->state = eCONTENT;
}
// reset bETag flag
bETag = FALSE;
} else if( bETag == TRUE ) { // file is done
break;
} else {
rc = IXML_FAILED;
goto ErrorHandler;
}
Parser_freeNodeContent( &newNode );
}
if( xmlParser->pCurElement != NULL ) {
rc = IXML_SYNTAX_ERR;
goto ErrorHandler;
}
*retDoc = ( IXML_Document * ) gRootDoc;
Parser_free( xmlParser );
return rc;
ErrorHandler:
Parser_freeNodeContent( &newNode );
ixmlDocument_free( gRootDoc );
Parser_free( xmlParser );
return rc;
}
/*==============================================================================*
* Parser_setLastElem
* set the last element to be the given string.
* Internal to parser only.
*
*===============================================================================*/
static int
Parser_setLastElem( IN Parser * xmlParser,
IN const char *s )
{
int rc;
if( ( xmlParser == NULL ) || ( s == NULL ) ) {
return IXML_FAILED;
}
rc = ixml_membuf_assign_str( &( xmlParser->lastElem ), s );
return rc;
}
/*==============================================================================*
*
* Parser_clearTokenBuf
* clear token buffer.
* Internal to parser only.
*
*===============================================================================*/
static void
Parser_clearTokenBuf( IN Parser * xmlParser )
{
ixml_membuf_destroy( &( xmlParser->tokenBuf ) );
}
/*==============================================================================*
*
* Parser_appendTokBufStr
* Appends string s to token buffer
* Internal to parser only.
*
*===============================================================================*/
static int
Parser_appendTokBufStr( IN Parser * xmlParser,
IN const char *s )
{
int rc = IXML_SUCCESS;
if( s != NULL ) {
rc = ixml_membuf_append_str( &( xmlParser->tokenBuf ), s );
}
return rc;
}
/*==============================================================================*
*
* Parser_appendTokBufChar
* Appends c to token buffer.
* Internal to parser only.
*
*===============================================================================*/
static int
Parser_appendTokBufChar( IN Parser * xmlParser,
IN char c )
{
int rc;
rc = ixml_membuf_append( &( xmlParser->tokenBuf ), &c );
return rc;
}
/*==============================================================================*
*
* Parser_skipWhiteSpaces
* skip white spaces
* Internal to parser only
*
*===============================================================================*/
static void
Parser_skipWhiteSpaces( IN Parser * xmlParser )
{
while( ( *( xmlParser->curPtr ) != 0 ) &&
( strchr( WHITESPACE, *( xmlParser->curPtr ) ) != NULL ) ) {
xmlParser->curPtr++;
}
}
/*==============================================================================*
* Parser_getChar
* returns next char value and its length
* Internal to parser only
*
*===============================================================================*/
static int
Parser_getChar( IN char *src,
INOUT int *cLen )
{
char *pnum;
int sum;
char c;
int i;
if( src == NULL || cLen == NULL ) {
return -1;
}
*cLen = 0;
if( *src != '&' ) {
if( *src > 0 && Parser_isXmlChar( *src ) ) {
*cLen = 1;
return *src;
}
i = Parser_UTF8ToInt( src, cLen );
if( !Parser_isXmlChar( i ) ) {
return -1;
}
return i;
} else if( strncasecmp( src, QUOT, strlen( QUOT ) ) == 0 ) {
*cLen = strlen( QUOT );
return '"';
} else if( strncasecmp( src, LT, strlen( LT ) ) == 0 ) {
*cLen = strlen( LT );
return '<';
} else if( strncasecmp( src, GT, strlen( GT ) ) == 0 ) {
*cLen = strlen( GT );
return '>';
} else if( strncasecmp( src, APOS, strlen( APOS ) ) == 0 ) {
*cLen = strlen( APOS );
return '\'';
} else if( strncasecmp( src, AMP, strlen( AMP ) ) == 0 ) {
*cLen = strlen( AMP );
return '&';
} else if( strncasecmp( src, ESC_HEX, strlen( ESC_HEX ) ) == 0 ) { // Read in escape characters of type &#xnn where nn is a hexadecimal value
pnum = src + strlen( ESC_HEX );
sum = 0;
while( strchr( HEX_NUMBERS, *pnum ) != 0 ) {
c = *pnum;
if( c <= '9' ) {
sum = sum * 16 + ( c - '0' );
} else if( c <= 'F' ) {
sum = sum * 16 + ( c - 'A' + 10 );
} else {
sum = sum * 16 + ( c - 'a' + 10 );
}
pnum++;
}
if( ( pnum == src ) || *pnum != ';' || !Parser_isXmlChar( sum ) ) {
return -1;
}
*cLen = pnum - src + 1;
return sum;
} else if( strncasecmp( src, ESC_DEC, strlen( ESC_DEC ) ) == 0 ) {
// Read in escape characters of type &#nn where nn is a decimal value
pnum = src + strlen( ESC_DEC );
sum = 0;
while( strchr( DEC_NUMBERS, *pnum ) != 0 ) {
sum = sum * 10 + ( *pnum - '0' );
pnum++;
}
if( ( pnum == src ) || *pnum != ';' || !Parser_isXmlChar( sum ) ) {
return -1;
}
*cLen = pnum - src + 1;
return sum;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -