⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mcbxml.c

📁 一个用C语言实现的XML解析工具.可以解析,生成XML文件.
💻 C
📖 第 1 页 / 共 5 页
字号:
 *
 * @return      LPTSTR
 *
 * @exception   none
 *
 * @author      Martyn C Brown
 *
 * @changeHistory  
 *	18th August    	2001	 - 	(V1.0) Creation (MCB)
 ****************************************************************************
 */
LPTSTR McbStrdup(LPCTSTR lpszData, int cbData)
{
	LPTSTR lpszNew;

	assert(lpszData);

	if (cbData == 0) cbData = _tcslen(lpszData);

	lpszNew = malloc((cbData+1) * sizeof(TCHAR));

	if (lpszNew)
	{
		memcpy(lpszNew, lpszData, (cbData) * sizeof(TCHAR));
		lpszNew[cbData] = (TCHAR)NULL;
	}

	return lpszNew;

}/* McbStrdup */

/**
 ****************************************************************************
 * <P> Find the next token in a string.  </P>
 *
 * @methodName  McbGetNextToken
 *
 * @param       *pXML		
 * @param       *pcbToken		
 * @param       *pType		
 *
 * @return      LPCTSTR
 *
 * @exception   none
 *
 * @author      Martyn C Brown
 *
 * @changeHistory  
 *	17th August    	2001	 - 	(V1.0) Creation (MCB)
 ****************************************************************************
 */
McbNextToken McbGetNextToken(McbXML *pXML, int *pcbToken, McbTokenType *pType)
{
	McbNextToken		result;
	LPCTSTR			lpXML;
	TCHAR			ch;
	TCHAR			chTemp;
	int				nSize;
	int				nFoundMatch;
	int				nExit;
	int				n;
	LPCTSTR			lpszOpen;
	int				cbOpen;
	int				nIsText = FALSE;

   /*
    *************************************************************************
    * Find next non-whte space character
    *************************************************************************
    */
	ch = McbFindNonWhiteSpace(pXML);

	if (ch)
	{
       /*
        *********************************************************************
        * Cache the current string pointer
        *********************************************************************
        */
		lpXML = pXML->lpXML;
		result.pStr = &lpXML[pXML->nIndex-1];

       /*
        *********************************************************************
        * First check whether the token is in the clear tag list (meaning it 
		* does not need formatting).
        *********************************************************************
        */
		n = 0;

		while(TRUE)
		{
           /*
            *****************************************************************
            * Obtain the name of the open part of the clear tag
            *****************************************************************
            */
			lpszOpen = pXML->pClrTags[n].lpszOpen;

			if (lpszOpen)
			{
               /*
                *************************************************************
                * Compare the open tag with the current token
                *************************************************************
                */
				cbOpen = _tcslen(lpszOpen);

				if (_tcsnicmp(lpszOpen, result.pStr, cbOpen) == 0)
				{
					result.pClr = &pXML->pClrTags[n];
					pXML->nIndex += cbOpen-1;
					*pType  = eTokenClear;
					return result;
				}

				n++;
			}
			else
			{
				break;
			}
		}

       /*
        *********************************************************************
        * If we didn't find a clear tag then check for standard tokens
        *********************************************************************
        */
		chTemp = 0;

		lpXML = pXML->lpXML;
		
		switch(ch)
		{
       /*
        *********************************************************************
        * Check for quotes
        *********************************************************************
        */
		case _T('\''):
		case _T('\"'):

           /*
            *****************************************************************
            * Type of token
            *****************************************************************
            */
			*pType = eTokenQuotedText;

			chTemp = ch;

           /*
            *****************************************************************
            * Set the size
            *****************************************************************
            */			
			nSize = 1;

			nFoundMatch = FALSE;

           /*
            *****************************************************************
            * Search through the string to find a matching quote
            *****************************************************************
            */
			while(ch = McbGetNextChar(pXML))
			{
				nSize++;

				if (ch == chTemp)
				{
					nFoundMatch = TRUE;
					break;
				}
			}

           /*
            *****************************************************************
            * If we failed to find a matching quote
            *****************************************************************
            */
			if (nFoundMatch == FALSE)
			{
               /*
                *************************************************************
                * Indicate error
                *************************************************************
                */
				pXML->error = eXMLErrorNoMatchingQuote;				
				*pType = eTokenError;
			}

			/* MCB 4.02.2002 */
			if (McbFindNonWhiteSpace(pXML))
			{
				pXML->nIndex--;
			}

			break;

       /*
        *********************************************************************
        * Equals (used with attribute values)
        *********************************************************************
        */
		case _T('='):
			nSize = 1;
			*pType = eTokenEquals;
			break;

       /*
        *********************************************************************
        * Close tag
        *********************************************************************
        */
		case _T('>'):
			nSize = 1;
			*pType = eTokenCloseTag;
			break;

       /*
        *********************************************************************
        * Check for tag start and tag end
        *********************************************************************
        */
		case _T('<'):

           /*
            *****************************************************************
            * Peek at the next character to see if we have an end tag '</',
			* or an xml declaration '<?'
            *****************************************************************
            */
			chTemp = pXML->lpXML[pXML->nIndex];

           /*
            *****************************************************************
            * If we have a tag end...
            *****************************************************************
            */
			if (chTemp == _T('/'))
			{
               /*
                *************************************************************
                * Set the type and ensure we point at the next character 
                *************************************************************
                */
				McbGetNextChar(pXML);
				*pType = eTokenTagEnd;
				nSize = 2;
			}
           /*
            *****************************************************************
            * If we have an XML declaration tag
            *****************************************************************
            */
			else if (chTemp == _T('?'))
			{
               /*
                *************************************************************
                * Set the type and ensure we point at the next character 
                *************************************************************
                */
				McbGetNextChar(pXML);
				*pType = eTokenDeclaration;
				nSize = 2;
			}
           /*
            *****************************************************************
            * Otherwise we must have a start tag
            *****************************************************************
            */
            else 
			{
				*pType = eTokenTagStart;
				nSize = 1;
			}
			break;

       /*
        *********************************************************************
        * Check to see if we have a short hand type end tag ('/>').
        *********************************************************************
        */
		case _T('/'):
		   /*
            *****************************************************************
            * Peek at the next character to see if we have an end tag '</'
			* or an xml declaration '<?'
            *****************************************************************
            */
			chTemp = pXML->lpXML[pXML->nIndex];

           /*
            *****************************************************************
            * If we have a short hand end tag...
            *****************************************************************
            */
			if (chTemp == _T('>'))
			{
               /*
                *************************************************************
                * Set the type and ensure we point at the next character 
                *************************************************************
                */
				McbGetNextChar(pXML);
				*pType = eTokenShortHandClose;
				nSize = 2;
				break;
			}

           /*
            *****************************************************************
            * If we haven't found a short hand closing tag then drop into the
			* text process
            *****************************************************************
            */

       /*
        *********************************************************************
        * Other characters
        *********************************************************************
        */
		default:
			nIsText = TRUE;
		}

       /*
        *********************************************************************
        * If this is a TEXT node
        *********************************************************************
        */
		if (nIsText)
		{
           /*
            *****************************************************************
            * Indicate we are dealing with text
            *****************************************************************
            */
			*pType = eTokenText;

			nSize = 1;
			nExit = FALSE;

			while((nExit == FALSE) && (ch = McbGetNextChar(pXML)))
			{
                switch(ch)
                {
               /*
                *************************************************************
                * Break when we find white space
                *************************************************************
                */
                case _T('\n'):
                case _T(' '):
                case _T('\t'):
                case _T('\r'):
					nExit = TRUE;
                    break;

               /*
                *************************************************************
                * If we find a slash then this maybe text or a short hand end
				* tag.
                *************************************************************
                */
				case _T('/'):
                   /*
                    *********************************************************
                    * Peek at the next character to see it we have short hand
					* end tag
                    *********************************************************
                    */
					chTemp = pXML->lpXML[pXML->nIndex];

                   /*
                    *********************************************************
                    * If we found a short hand end tag then we need to exit 
					* the loop
                    *********************************************************
                    */
					if (chTemp == _T('>'))
					{
						pXML->nIndex--; /* MCB 03.02.2002 */
						nExit = TRUE;
					}
					else
					{
						nSize++;
					}
					break;

               /*
                *************************************************************
                * Break when we find a terminator and decrement the index and
				* column count so that we are pointing at the right character
				* the next time we are called.
                *************************************************************
                */
				case _T('<'):
				case _T('>'):
				case _T('='):
					pXML->nIndex--;					
					nExit = TRUE;
					break;

				case 0:
					nExit = TRUE;
					break;

				default:
					nSize++;
                }
			}
		}

		*pcbToken = nSize;
	}
   /*
    *************************************************************************
    * If we failed to obtain a valid character
    *************************************************************************
    */
    else 
    {
   		*pcbToken = 0;
		*pType = eTokenError;
    }

	return result;

}/* McbGetNextToken */

/**
 ****************************************************************************
 * <P> Parse XML errors into a user friendly string.  </P>
 *
 * @methodName  McbGetError
 *
 * @param       error		
 *
 * @return      LPCTSTR
 *
 * @exception   none
 *
 * @author      Martyn C Brown
 *
 * @changeHistory  
 *	19th August    	2001	 - 	(V1.0) Creation (MCB)
 ****************************************************************************
 */
LPCTSTR McbGetError(McbXMLError error)
{
	LPCTSTR lpszErr = _T("Unknown");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -