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

📄 mcbxml.c

📁 一个用C语言实现的XML解析工具.可以解析,生成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;

/*
 ****************************************************************************
 * Structure used to obtain List.
 ****************************************************************************
 */
typedef struct List_ST{
	struct List_ST *pNext;
	struct List_ST *pPrev;
}List_st;

typedef struct{
	List_st pList;
	int iNum;
}ListHead_st;

/*
 ****************************************************************************
 * Structure used to obtain List Node.
 ****************************************************************************
 */

#ifdef DYNAMIC_MEM
typedef struct{
	List_st List;
	LPTSTR lpszText;
}NodeText_st;
#else
typedef struct{
	List_st List;
	char lpszText[256];
}NodeText_st;
#endif

static ListHead_st g_StrList;

void InitList(ListHead_st *pListHead)
{
	pListHead->pList.pNext = &(pListHead->pList);
	pListHead->pList.pPrev = &(pListHead->pList);
	pListHead->iNum = 0;
}/* InitList */

void AddToList(ListHead_st *pListHead,List_st *pListNode)
{
	pListNode->pPrev = &(pListHead->pList);
	pListNode->pNext = pListHead->pList.pNext;

	pListHead->pList.pNext->pPrev = pListNode;
	pListHead->pList.pNext = pListNode;
	pListHead->iNum++;
}/* AddToList */

List_st *DeleteFromListTial(ListHead_st *pListHead)
{
	List_st *pTemp;
	//Empty List?
	if(pListHead->pList.pPrev == &(pListHead->pList))
		return 0;
	pTemp = pListHead->pList.pPrev;
	pTemp->pPrev->pNext = pTemp->pNext;
	pTemp->pNext->pPrev = pTemp->pPrev;
	pListHead->iNum--;
	return pTemp;
}/* DeleteFromListTial */

void DeleteFromList(List_st *pList)
{
	pList->pNext->pPrev = pList->pPrev;
	pList->pPrev->pPrev = pList->pNext;
}/*  DeleteFromList */

void FreeList(ListHead_st *pListHead)
{
	List_st *pList;
	NodeText_st *pNodeText;
	//empty List
	if(pListHead->pList.pNext == &(pListHead->pList))
		return;
	while(pListHead->iNum){
		pList = DeleteFromListTial(pListHead);
		pNodeText = ListEntry(pList,NodeText_st,List);
#ifdef DYNAMIC_MEM
		free(pNodeText->lpszText);
#endif
		free(pNodeText);
	}

}/*FreeList*/

/**
 ****************************************************************************
 * <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);
	//Init the NodeName LinkList
	//Toby add 2006/7/3/9:31
	//InitList(&g_StrList);
	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);
	//FreeList(&g_StrList);

}/* 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		

⌨️ 快捷键说明

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