📄 mcbxml.c
字号:
/**
****************************************************************************
* <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 + -