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

📄 mcbxml.c

📁 解析xml为树状结构
💻 C
📖 第 1 页 / 共 5 页
字号:
 * @methodName  * McbAddClear
 *
 * @param       *pEntry		
 * @param       lpszValue		
 * @param       nGrowBy		
 *
 * @return      McbXMLClear
 *
 * @exception   none
 *
 * @author      Martyn C Brown
 *
 * @changeHistory  
 *	20th August    	2001	 - 	(V1.0) Creation (MCB)
 ****************************************************************************
 */
McbXMLClear * McbAddClear(McbXMLElement *pEntry, LPTSTR lpszValue, 
						McbClearTag *pClear, int nGrowBy)
{
	McbXMLNode *pNode;
	McbXMLClear *pNewClear;

	assert(pEntry);
	assert(nGrowBy > 0);

   /*
    *************************************************************************
    * Check we have enough storage
    *************************************************************************
    */
	if (pEntry->nSize == pEntry->nMax)
	{
		McbAllocNodes(pEntry, nGrowBy);
	}

   /*
    *************************************************************************
    * Obtain the new node, set the type and initialise it.
    *************************************************************************
    */
	pNode = &pEntry->pEntries[pEntry->nSize];
	pNode->type = eNodeClear;

	pNewClear = malloc(sizeof(McbXMLClear));
	pNode->node.pClear = pNewClear;
	pNewClear->lpszValue = lpszValue;
	pNewClear->lpszOpenTag = pClear->lpszOpen;
	pNewClear->lpszCloseTag = pClear->lpszClose;

   /*
    *************************************************************************
    * Increment the number of contained nodes
    *************************************************************************
    */
	pEntry->nSize++;

   /*
    *************************************************************************
    * Return the new attribute.
    *************************************************************************
    */
	return pNewClear;

}/* McbAddClear */

/**
 ****************************************************************************
 * <P> Enumerate nodes in the list.  </P>
 *
 * @methodName  McbEnumNodes
 *
 * @param       *pEntry		
 * @param       *pnIndex		
 *
 * @return      McbXMLNode
 *
 * @exception   none
 *
 * @author      Martyn C Brown
 *
 * @changeHistory  
 *	20th August    	2001	 - 	(V1.0) Creation (MCB)
 ****************************************************************************
 */
McbXMLNode * McbEnumNodes(McbXMLElement *pEntry, int *pnIndex)
{	
	McbXMLNode * pResult = NULL;

	assert(pnIndex);
	assert(pEntry);

	if (*pnIndex < pEntry->nSize)
	{
		pResult = &pEntry->pEntries[*pnIndex];
		(*pnIndex)++;
	}

	return pResult;

}/* McbEnumNodes */

/**
 ****************************************************************************
 * <P> Enumerate elements on a base element.  </P>
 *
 * @methodName  McbEnumElements
 *
 * @param       *pEntry		
 * @param       *pnIndex		
 *
 * @return      McbXMLNode
 *
 * @exception   none
 *
 * @author      Martyn C Brown
 *
 * @changeHistory  
 *	20th August    	2001	 - 	(V1.0) Creation (MCB)
 ****************************************************************************
 */
McbXMLElement * McbEnumElements(McbXMLElement *pEntry, int *pnIndex)
{	
	McbXMLElement * pResult = NULL;
	int nIndex;

	assert(pnIndex);
	assert(pEntry);

	nIndex = *pnIndex;

	for (;nIndex < pEntry->nSize && !pResult; nIndex++)
	{
		if (pEntry->pEntries[nIndex].type == eNodeElement)
		{
			pResult = pEntry->pEntries[nIndex].node.pElement;
		}
	}

	*pnIndex = nIndex;

	return pResult;

}/* McbEnumElements */

/**
 ****************************************************************************
 * <P> Enumerate attributes on a base element.  </P>
 *
 * @methodName  McbEnumAttributes
 *
 * @param       *pEntry		
 * @param       *pnIndex		
 *
 * @return      McbXMLNode
 *
 * @exception   none
 *
 * @author      Martyn C Brown
 *
 * @changeHistory  
 *	20th August    	2001	 - 	(V1.0) Creation (MCB)
 ****************************************************************************
 */
McbXMLAttribute * McbEnumAttributes(McbXMLElement *pEntry, int *pnIndex)
{	
	McbXMLAttribute * pResult = NULL;
	int nIndex;

	assert(pnIndex);
	assert(pEntry);

	nIndex = *pnIndex;

	for (;nIndex < pEntry->nSize && !pResult; nIndex++)
	{
		if (pEntry->pEntries[nIndex].type == eNodeAttribute)
		{
			pResult = pEntry->pEntries[nIndex].node.pAttrib;
		}
	}

	*pnIndex = nIndex;

	return pResult;

}/* McbEnumAttributes */

/**
 ****************************************************************************
 * <P> Trim the end of the text to remove white space characters.  </P>
 *
 * @methodName  McbFindEndOfText
 *
 * @param       lpszToken		
 * @param       *pcbText		
 *
 * @return      void
 *
 * @exception   none
 *
 * @author      Martyn C Brown
 *
 * @changeHistory  
 *	20th August    	2001	 - 	(V1.0) Creation (MCB)
 ****************************************************************************
 */
void McbFindEndOfText(LPCTSTR lpszToken, int *pcbText)
{
	TCHAR	ch;
	int		cbText;

	assert(lpszToken);
	assert(pcbText);

	cbText = (*pcbText)-1;	

	while(TRUE)
	{
		assert(cbText >= 0);

		ch = lpszToken[cbText];

		switch(ch)
		{
		case _T('\r'):
		case _T('\n'):
		case _T('\t'):
		case _T(' '):
			cbText--;
			break;

		default:
			*pcbText = cbText+1;
			return;
		}
	}

}/* McbFindEndOfText */

/**
 ****************************************************************************
 * <P> Parse a clear (unformatted) type node.  </P>
 *
 * @methodName  McbParseClearTag
 *
 * @param       *pXML		
 * @param       *pElement		
 * @param       lpszClose		
 * @param       lpszToken		
 *
 * @return      int
 *
 * @exception   none
 *
 * @author      Martyn C Brown
 *
 * @changeHistory  
 *	26th August    	2001	 - 	(V1.0) Creation (MCB)
 ****************************************************************************
 */
int McbParseClearTag(McbXML *pXML, McbXMLElement *pElement, McbClearTag * pClear)
{
	int cbTemp = 0;

	LPTSTR lpszTemp;
	LPCTSTR lpszXML = &pXML->lpXML[pXML->nIndex];

   /*
    *************************************************************************
    * Find the closing tag
    *************************************************************************
    */
	lpszTemp = _tcsstr(lpszXML, pClear->lpszClose);

   /*
    *************************************************************************
    * Iterate through the tokens until we find the closing tag.
    *************************************************************************
    */
    if (lpszTemp)
    {
       /*
        *********************************************************************
        * Cache the size and increment the index
        *********************************************************************
        */
        cbTemp = lpszTemp - lpszXML;

		pXML->nIndex += cbTemp;
		pXML->nIndex += _tcslen(pClear->lpszClose);
        
       /*
        *********************************************************************
        * Add the clear node to the current element
        *********************************************************************
        */
        lpszTemp = McbStrdup(lpszXML, cbTemp);

        McbAddClear(pElement, lpszTemp, pClear, McbGROWBY);

#ifdef McbSTOREOFFSETS
		pElement->pEntries[pElement->nSize-1].nStringOffset = (lpszXML -
			_tcslen(pClear->lpszOpen)) - pXML->lpXML;			
#endif /* McbSTOREOFFSETS */

        return TRUE;
    }
   /*
    *************************************************************************
    * If we failed to find the end tag
    *************************************************************************
    */
    else
    {
        pXML->error = eXMLErrorUnmatchedEndTag;
        return FALSE;
    }

}/* McbParseClearTag */

/**
 ****************************************************************************
 * <P> Recursively parse an XML element.  </P>
 *
 * @methodName  McbParseXMLElement
 *
 * @param       *pXML		
 * @param       * pElement		
 *
 * @return      int
 *
 * @exception   none
 *
 * @author      Martyn C Brown
 *
 * @changeHistory  
 *	19th August    	2001	 - 	(V1.0) Creation (MCB)
 ****************************************************************************
 */
int McbParseXMLElement(McbXML *pXML, McbXMLElement * pElement)
{
	LPCTSTR lpszToken;
	int cbToken;

	enum McbTokenType type;
	McbNextToken token;

	LPCTSTR lpszTemp;
	int cbTemp;

	int nDeclaration;

	LPCTSTR lpszText = NULL;

	McbXMLElement *pNew;

	enum McbStatus status;
	enum McbAttrib attrib = eAttribName;

	assert(pXML);
	assert(pElement);

   /*
    *************************************************************************
    * If this is the first call to the function
    *************************************************************************
    */
	if (pXML->nFirst)
	{
       /*
        *********************************************************************
        * Assume we are outside of a tag definition
        *********************************************************************
        */
		pXML->nFirst = FALSE;
		status = eOutsideTag;
	}
   /*
    *************************************************************************
    * If this is not the first call then we should only be called when inside
	* a tag.
    *************************************************************************
    */
    else 
	{
		status = eInsideTag;
	}

   /*
    *************************************************************************
    * Iterate through the tokens in the document
    *************************************************************************
    */
	while(TRUE)
	{
       /*
        *********************************************************************
        * Obtain the next token
        *********************************************************************
        */
		token = McbGetNextToken(pXML, &cbToken, &type);

 		if (type != eTokenError)
		{
           /*
            *****************************************************************
            * Check the current status
            *****************************************************************
            */
			switch(status)
			{
           /*
            *****************************************************************
            * If we outside of a tag definition
            *****************************************************************
            */
			case eOutsideTag:
               /*
                *************************************************************
                * Check what type of token we obtained
                *************************************************************
                */
				switch(type)
				{
               /*
                *************************************************************
                * If we have found text or quoted text
                *************************************************************
                */
				case eTokenText:
				case eTokenQuotedText:
				case eTokenEquals:
					if (!lpszText)
					{
						lpszText = token.pStr;
					}					

					break;				

               /*
                *************************************************************
                * If we found a start tag '<' and declarations '<?'
                *************************************************************
                */
				case eTokenTagStart:
				case eTokenDeclaration:
                   /*

⌨️ 快捷键说明

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