📄 ixmlparser.c
字号:
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 intParser_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 intParser_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 BOOLParser_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 BOOLParser_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 intParser_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_MEMORY; } node->nodeType = eCDATA_SECTION_NODE; *pSrc = pEnd + strlen( CDEND ); return IXML_SUCCESS; } else { return IXML_SYNTAX_ERR; }}/*==============================================================================*** Parser_setElementNamespace* set element's namespace* Internal to parser only. **===============================================================================*/static intParser_setElementNamespace( IN IXML_Element * newElement, IN char *nsURI ){ if( newElement != NULL ) { if( newElement->n.namespaceURI != NULL ) { return IXML_SYNTAX_ERR; } else { ( newElement->n ).namespaceURI = strdup( nsURI ); if( ( newElement->n ).namespaceURI == NULL ) { return IXML_INSUFFICIENT_MEMORY; } } } return IXML_SUCCESS;}/*==============================================================================*** Parser_processContent* processes the CONTENT as defined in XML spec.* Internal to parser only **===============================================================================*/static intParser_processContent( IN Parser * xmlParser, IN IXML_Node * node ){ char *pEndContent; BOOL bReadContent; int tokenLength; char *notAllowed = "]]>"; char *pCurToken = NULL; // save pointer for backup xmlParser->savePtr = xmlParser->curPtr; Parser_skipWhiteSpaces( xmlParser ); if( *( xmlParser->curPtr ) == '\0' ) { // end of file is reached return IXML_SUCCESS; } pEndContent = xmlParser->curPtr; if( *pEndContent == LESSTHAN ) { if( strncmp( pEndContent, ( char * )CDSTART, strlen( CDSTART ) ) == 0 ) { if( Parser_processCDSect( &pEndContent, node ) != IXML_SUCCESS ) { return IXML_SYNTAX_ERR; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -