📄 ixmlparser.c
字号:
static int
Parser_addNamespace( IN Parser * xmlParser )
{
IXML_Node *pNode;
IXML_ElementStack *pCur;
char *namespaceUri;
pNode = xmlParser->pNeedPrefixNode;
pCur = xmlParser->pCurElement;
if( pNode->prefix == NULL ) { // element does not have prefix
if( strcmp( pNode->nodeName, pCur->element ) != 0 ) {
return IXML_FAILED;
}
if( pCur->namespaceUri != NULL ) {
// it would be wrong that pNode->namespace != NULL.
assert( pNode->namespaceURI == NULL );
pNode->namespaceURI = strdup( pCur->namespaceUri );
if( pNode->namespaceURI == NULL ) {
return IXML_INSUFFICIENT_MEMORY;
}
}
xmlParser->pNeedPrefixNode = NULL;
} else {
if( ( strcmp( pNode->nodeName, pCur->element ) != 0 ) &&
( strcmp( pNode->prefix, pCur->prefix ) != 0 ) ) {
return IXML_FAILED;
}
namespaceUri = Parser_getNameSpace( xmlParser, pCur->prefix );
if( namespaceUri != NULL ) {
pNode->namespaceURI = strdup( namespaceUri );
if( pNode->namespaceURI == NULL ) {
return IXML_INSUFFICIENT_MEMORY;
}
xmlParser->pNeedPrefixNode = NULL;
}
}
return IXML_SUCCESS;
}
/*==============================================================================*
*
* Parser_setNodePrefixAndLocalName
* set the node prefix and localName as defined by the nodeName
* in the form of ns:name
* Internal to parser only.
*
*===============================================================================*/
int
Parser_setNodePrefixAndLocalName( IN IXML_Node * node )
{
char *pStrPrefix = NULL;
char *pLocalName;
int nPrefix;
assert( node != NULL );
if( node == NULL ) {
return IXML_FAILED;
}
pStrPrefix = strchr( node->nodeName, ':' );
if( pStrPrefix == NULL ) {
node->prefix = NULL;
node->localName = strdup( node->nodeName );
if( node->localName == NULL ) {
return IXML_INSUFFICIENT_MEMORY;
}
} else { // fill in the local name and prefix
pLocalName = ( char * )pStrPrefix + 1;
nPrefix = pStrPrefix - node->nodeName;
node->prefix = malloc( nPrefix + 1 );
if( node->prefix == NULL ) {
return IXML_INSUFFICIENT_MEMORY;
}
memset( node->prefix, 0, nPrefix + 1 );
strncpy( node->prefix, node->nodeName, nPrefix );
node->localName = strdup( pLocalName );
if( node->localName == NULL ) {
free( node->prefix );
node->prefix = NULL; //no need to free really, main loop will frees it
//when return code is not success
return IXML_INSUFFICIENT_MEMORY;
}
}
return IXML_SUCCESS;
}
/*==============================================================================*
*
* Parser_xmlNamespace
* add namespace definition.
* internal to parser only.
*
*===============================================================================*/
static int
Parser_xmlNamespace( IN Parser * xmlParser,
IN IXML_Node * newNode )
{
IXML_ElementStack *pCur = xmlParser->pCurElement;
IXML_NamespaceURI *pNewNs = NULL,
*pNs = NULL,
*pPrevNs = NULL;
int rc;
// if the newNode contains a namespace definition
assert( newNode->nodeName != NULL );
if( strcmp( newNode->nodeName, "xmlns" ) == 0 ) // default namespace def.
{
if( pCur->namespaceUri != NULL ) {
free( pCur->namespaceUri );
}
pCur->namespaceUri = strdup( newNode->nodeValue );
if( pCur->namespaceUri == NULL ) {
return IXML_INSUFFICIENT_MEMORY;
}
} else if( strncmp( newNode->nodeName, "xmlns:", strlen( "xmlns:" ) ) == 0 ) { // namespace definition
rc = Parser_setNodePrefixAndLocalName( newNode );
if( rc != IXML_SUCCESS ) {
return rc;
}
assert( newNode->localName != NULL );
if( pCur == NULL ) {
return IXML_FAILED;
}
if( ( pCur->prefix != NULL )
&& ( strcmp( pCur->prefix, newNode->localName ) == 0 ) ) {
pCur->namespaceUri = strdup( newNode->nodeValue );
if( pCur->namespaceUri == NULL ) {
return IXML_INSUFFICIENT_MEMORY;
}
} else {
pPrevNs = pCur->pNsURI;
pNs = pPrevNs;
while( pNs != NULL ) {
if( ( pNs->prefix != NULL ) &&
( strcmp( pNs->prefix, newNode->localName ) == 0 ) ) {
break; // replace namespace definition
} else {
pPrevNs = pNs;
pNs = pNs->nextNsURI;
}
}
if( pNs == NULL ) // a new definition
{
pNewNs =
( IXML_NamespaceURI * )
malloc( sizeof( IXML_NamespaceURI ) );
if( pNewNs == NULL ) {
return IXML_INSUFFICIENT_MEMORY;
}
memset( pNewNs, 0, sizeof( IXML_NamespaceURI ) );
pNewNs->prefix = strdup( newNode->localName );
if( pNewNs->prefix == NULL ) {
free( pNewNs );
return IXML_INSUFFICIENT_MEMORY;
}
pNewNs->nsURI = strdup( newNode->nodeValue );
if( pNewNs->nsURI == NULL ) {
Parser_freeNsURI( pNewNs );
free( pNewNs );
return IXML_INSUFFICIENT_MEMORY;
}
if( pCur->pNsURI == NULL ) {
pCur->pNsURI = pNewNs;
} else {
pPrevNs->nextNsURI = pNewNs;
}
} else // udpate the namespace
{
if( pNs->nsURI != NULL ) {
free( pNs->nsURI );
}
pNs->nsURI = strdup( newNode->nodeValue );
if( pNs->nsURI == NULL ) {
return IXML_INSUFFICIENT_MEMORY;
}
}
}
}
if( xmlParser->pNeedPrefixNode != NULL ) {
rc = Parser_addNamespace( xmlParser );
return rc;
} else {
return IXML_SUCCESS;
}
}
/*==============================================================================*
*
* Parser_processSTag:
* Processes the STag as defined by XML spec.
* Internal to parser only.
*
*===============================================================================*/
static int
Parser_processSTag( IN Parser * xmlParser,
IN IXML_Node * node )
{
char *pCurToken = NULL;
int rc;
if( Parser_getNextToken( xmlParser ) == 0 ) {
return IXML_SYNTAX_ERR;
}
pCurToken = ( xmlParser->tokenBuf ).buf;
if( pCurToken != NULL ) {
node->nodeName = strdup( pCurToken );
if( node->nodeName == NULL ) {
return IXML_INSUFFICIENT_MEMORY;
}
} else {
return IXML_SYNTAX_ERR;
}
rc = Parser_setLastElem( xmlParser, node->nodeName );
if( rc != IXML_SUCCESS ) { // no need to free node->nodeName, main loop will free it
return IXML_FAILED;
}
rc = Parser_setNodePrefixAndLocalName( node );
if( rc != IXML_SUCCESS ) { // no need to free node->nodeName, main loop will free it
return IXML_FAILED;
}
node->nodeValue = NULL;
node->nodeType = eELEMENT_NODE;
xmlParser->savePtr = xmlParser->curPtr;
if( Parser_getNextToken( xmlParser ) == 0 ) { // no need to free node->nodeName, main loop will free it
return IXML_SYNTAX_ERR;
}
pCurToken = ( xmlParser->tokenBuf ).buf;
// check to see what is the next token
if( strcmp( pCurToken, "/>" ) == 0 ) // empty element
{
xmlParser->state = eELEMENT;
xmlParser->curPtr = xmlParser->savePtr; // backup to />
} else if( strcmp( pCurToken, ">" ) == 0 ) // expecting text node
{
xmlParser->state = eCONTENT;
} else {
xmlParser->state = eATTRIBUTE;
xmlParser->curPtr = xmlParser->savePtr;
}
return IXML_SUCCESS;
}
/*==============================================================================*
*
* Parser_hasDefaultNamespace
* decide whether the current element has default namespace
* Internal to parser only.
*
*===============================================================================*/
static BOOL
Parser_hasDefaultNamespace( IN Parser * xmlParser,
IN IXML_Node * newNode,
IN char **nsURI )
{
IXML_ElementStack *pCur = xmlParser->pCurElement;
while( pCur != NULL ) {
if( ( pCur->prefix == NULL ) && ( pCur->namespaceUri != NULL ) ) {
*nsURI = pCur->namespaceUri;
return TRUE;
} else {
pCur = pCur->nextElement;
}
}
return FALSE;
}
/*==============================================================================*
*
* Parser_ElementPrefixDefined
* decides whether element's prefix is already defined.
* Internal to parser only.
*
*===============================================================================*/
static BOOL
Parser_ElementPrefixDefined( IN Parser * xmlParser,
IN IXML_Node * newNode,
IN char **nsURI )
{
IXML_ElementStack *pCur = xmlParser->pCurElement;
IXML_NamespaceURI *pNsUri;
while( pCur != NULL ) {
if( ( pCur->prefix != NULL )
&& ( strcmp( pCur->prefix, newNode->prefix ) == 0 ) ) {
*nsURI = pCur->namespaceUri;
return TRUE;
} else {
pNsUri = pCur->pNsURI;
while( pNsUri != NULL ) {
if( strcmp( pNsUri->prefix, newNode->prefix ) == 0 ) {
*nsURI = pNsUri->nsURI;
return TRUE;
} else {
pNsUri = pNsUri->nextNsURI;
}
}
}
pCur = pCur->nextElement;
}
return FALSE;
}
/*==============================================================================*
*
* Parser_processCDSect
* Processes CDSection as defined by XML spec.
* Internal to parser only.
*
*===============================================================================*/
static int
Parser_processCDSect( IN char **pSrc,
IN IXML_Node * node )
{
char *pEnd;
int tokenLength = 0;
char *pCDataStart;
if( *pSrc == NULL ) {
return IXML_FAILED;
}
pCDataStart = *pSrc + strlen( CDSTART );
pEnd = pCDataStart;
while( ( Parser_isXmlChar( *pEnd ) == TRUE ) && ( *pEnd != '0' ) ) {
if( strncmp( pEnd, CDEND, strlen( CDEND ) ) == 0 ) {
break;
} else {
pEnd++;
}
}
if( ( pEnd - pCDataStart > 0 ) && ( *pEnd != '0' ) ) {
tokenLength = pEnd - pCDataStart;
node->nodeValue = ( char * )malloc( tokenLength + 1 );
if( node->nodeValue == NULL ) {
return IXML_INSUFFICIENT_MEMORY;
}
strncpy( node->nodeValue, pCDataStart, tokenLength );
node->nodeValue[tokenLength] = '\0';
node->nodeName = strdup( CDATANODENAME );
if( node->nodeName == NULL ) {
// no need to free node->nodeValue at all, bacause node contents
// will be freed by the main loop.
return IXML_INSUFFICIENT_M
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -