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

📄 mcbxml.c

📁 解析xml为树状结构
💻 C
📖 第 1 页 / 共 5 页
字号:
/**
 ****************************************************************************
 * <P> McbXML.c - implementation file for basic XML parser written in ANSI C 
 * for portability.
 * It works by using recursion and a node tree for breaking down the elements
 * of an XML document.  </P>
 *
 * @version     V1.0
 *
 * @author      Martyn C Brown
 *
 * @changeHistory  
 *	21st August    	2001	 - 	(V1.0) Creation (MCB)
 ****************************************************************************
 */

/*
 ****************************************************************************
 * Include all necessary include files
 ****************************************************************************
 */
#include "McbXML.h"
#include <malloc.h>
#include <memory.h>
#include <assert.h>

/*
 ****************************************************************************
 * Enumeration used to decipher what type a token is
 ****************************************************************************
 */
typedef enum McbTokenType
{
	eTokenText = 0,
	eTokenQuotedText,
	eTokenTagStart,			/* "<"			*/
	eTokenTagEnd,			/* "</"			*/
	eTokenCloseTag,			/* ">"			*/
	eTokenEquals,			/* "="			*/
	eTokenDeclaration,		/* "<?"			*/
	eTokenShortHandClose,	/* "/>"			*/
	eTokenClear,
	eTokenError
} McbTokenType;

/*
 ****************************************************************************
 * Defines to dictate grow by value when adding nodes.
 ****************************************************************************
 */
#define McbGROWBY			5

#define McbINDENTCHAR	_T('\t')

typedef struct McbClearTag
{
	LPTSTR lpszOpen;
	LPTSTR lpszClose;

} McbClearTag;

typedef struct McbNextToken
{
	McbClearTag	*pClr;
	LPCTSTR		pStr;
} McbNextToken;

/*
 ****************************************************************************
 * Main structure used for parsing XML
 ****************************************************************************
 */
typedef struct McbXML
{
	LPCTSTR				lpXML;
	int					nIndex;
	enum McbXMLError		error;
	LPCTSTR				lpEndTag;
	int					cbEndTag;
	LPCTSTR				lpNewElement;
	int					cbNewElement;
	int					nFirst;
	McbClearTag			*pClrTags;

} McbXML;

/*
 ****************************************************************************
 * Enumeration used when parsing attributes
 ****************************************************************************
 */
typedef enum McbAttrib
{
	eAttribName = 0,
	eAttribEquals,
	eAttribValue
} McbAttrib;

/*
 ****************************************************************************
 * Enumeration used when parsing elements to dictate whether we are currently
 * inside a tag
 ****************************************************************************
 */
typedef enum McbStatus
{
	eInsideTag = 0,
	eOutsideTag
} McbStatus;

/**
 ****************************************************************************
 * <P> Initialise an element.  </P>
 *
 * @methodName  McbInitElement
 *
 * @param       *pEntry		
 * @param       lpszName		
 *
 * @return      void
 *
 * @exception   none
 *
 * @author      Martyn C Brown
 *
 * @changeHistory  
 *	14th August    	2001	 - 	(V1.0) Creation (MCB)
 ****************************************************************************
 */
void McbInitElement(McbXMLElement *pEntry, McbXMLElement *pParent, 
				   LPTSTR lpszName, int nIsDeclaration)
{
	assert(pEntry);

	pEntry->nMax = 0;
	pEntry->nSize = 0;
	pEntry->pEntries = NULL;
	pEntry->pParent = pParent;
	pEntry->nIsDeclaration = nIsDeclaration;
	pEntry->lpszName = lpszName;

}/* McbInitElement */

/**
 ****************************************************************************
 * <P> Create the root element.  </P>
 *
 * @methodName  * McbCreateRoot
 *
 * @param       none
 *
 * @return      McbXMLElement
 *
 * @exception   none
 *
 * @author      Martyn C Brown
 *
 * @changeHistory  
 *	1st February  	2002	 - 	(V1.0) Creation (MCB)
 ****************************************************************************
 */
McbXMLElement * McbCreateRoot()
{
	McbXMLElement * pElement;

	pElement = (McbXMLElement*)malloc(sizeof(McbXMLElement));
	McbInitElement(pElement, NULL, 0, FALSE);

	return pElement;

}/* McbCreateRoot */

/**
 ****************************************************************************
 * <P> Delete the root element and set it to NULL.  </P>
 *
 * @methodName  McbDeleteRoot
 *
 * @param       ** ppElement		
 *
 * @return      void
 *
 * @exception   none
 *
 * @author      Martyn C Brown
 *
 * @changeHistory  
 *	1st February  	2002	 - 	(V1.0) Creation (MCB)
 ****************************************************************************
 */
void McbDeleteRoot(McbXMLElement * pElement)
{
    McbDeleteElement(pElement);
	free(pElement);

}/* McbDeleteRoot */

/**
 ****************************************************************************
 * <P> Delete an attribute.  </P>
 *
 * @methodName  McbDeleteAttribute
 *
 * @param       *pEntry		
 *
 * @return      void
 *
 * @exception   none
 *
 * @author      Martyn C Brown
 *
 * @changeHistory  
 *	14th August    	2001	 - 	(V1.0) Creation (MCB)
 ****************************************************************************
 */
void McbDeleteAttribute(McbXMLAttribute *pEntry)
{
	assert(pEntry);

	if (pEntry->lpszName) 
	{
		free(pEntry->lpszName);
		pEntry->lpszName = NULL;
	}

	if (pEntry->lpszValue) 
	{
		free(pEntry->lpszValue);
		pEntry->lpszValue=  NULL;
	}

}/* McbDeleteAttribute */

/**
 ****************************************************************************
 * <P> Attach attributes from one list to another.  </P>
 *
 * @methodName  McbAttributeAttach
 *
 * @param       *pDst		
 * @param       *pSrc		
 * @param       nNum		
 *
 * @return      void
 *
 * @exception   none
 *
 * @author      Martyn C Brown
 *
 * @changeHistory  
 *	14th August    	2001	 - 	(V1.0) Creation (MCB)
 ****************************************************************************
 */
void McbAttributeAttach(McbXMLAttribute *pDst, McbXMLAttribute *pSrc, int nNum)
{
	int n;

	for (n=0; n<nNum; n++)
	{
		pDst[n].lpszName = pSrc[n].lpszName;
		pDst[n].lpszValue = pSrc[n].lpszValue;

		pSrc[n].lpszName = NULL;
		pSrc[n].lpszValue = NULL;
	}

}/* McbAttributeAttach */

/**
 ****************************************************************************
 * <P> Obtain the next character from the string.  </P>
 *
 * @methodName  McbGetNextChar
 *
 * @param       *pXML		
 *
 * @return      TCHAR
 *
 * @exception   none
 *
 * @author      Martyn C Brown
 *
 * @changeHistory  
 *	17th August    	2001	 - 	(V1.0) Creation (MCB)
 ****************************************************************************
 */
TCHAR McbGetNextChar(McbXML *pXML)
{
	TCHAR ch;

	ch = pXML->lpXML[pXML->nIndex];
	
	if (ch != 0) pXML->nIndex++;

	return ch;

}/* McbGetNextChar */

/**
 ****************************************************************************
 * <P> Find next non-white space character.  </P>
 *
 * @methodName  McbFindNonWhiteSpace
 *
 * @param       *pXML		
 *
 * @return      TCHAR
 *
 * @exception   none
 *
 * @author      Martyn C Brown
 *
 * @changeHistory  
 *	18th August    	2001	 - 	(V1.0) Creation (MCB)
 ****************************************************************************
 */
TCHAR McbFindNonWhiteSpace(McbXML *pXML)
{
	TCHAR ch;
	LPCTSTR lpXML = pXML->lpXML;
	int nExit = FALSE;

	assert(pXML);

   /*
    *************************************************************************
    * Iterate through characters in the string until we find a NULL or a
    * non-white space character
    *************************************************************************
    */
	while((nExit == FALSE) && (ch = McbGetNextChar(pXML)))
	{
		switch(ch)
		{
       /*
        *********************************************************************
        * Ignore white space
        *********************************************************************
        */
        case _T('\n'):
        case _T(' '):
		case _T('\t'):
		case _T('\r'):
			continue;			

		default:
			nExit = TRUE;

		}
	}

	return ch;

}/* McbFindNonWhiteSpace */

/**
 ****************************************************************************
 * <P> Duplicate a given string.  </P>
 *
 * @methodName  McbStrdup
 *
 * @param       lpszData		
 * @param       cbData		
 *
 * @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];

       /*
        *********************************************************************

⌨️ 快捷键说明

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