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

📄 cxml.c

📁 一个简单的在unix 处理xml解析的程序。程序流程简单功能清晰。对想自已写xml处理程序的应有一定的帮助
💻 C
📖 第 1 页 / 共 5 页
字号:
/*-------------------------------------------------------------------------*/
/*XML解释模块,师鹏超设计,支持W3C 1.0版本                                 */
/*此不支持DTD,支持实体引用,但不支持节点间的注内的注释                    */
/*此种注释被当成数据来对待                                                 */
/*    师鹏超                                                               */
/*    2005年06月24日                                                       */
/*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
#include "CXml.h"
#include "CCode.h"

BYTE nCharType;
/*-------------------------------------------------------------------------*/
/*常用内部函数说明*/
PXMLNODE STDCALL XML_AllocNode( IN LPCSTR pszName, IN LPCSTR pszData, IN PCNODEPROPERTY pProp );
RESULT STDCALL XML_FreeNode( IN PXMLNODE pNode );
void STDCALL XML_TransValue( IN LPCSTR pszMsg, OUT LPSTR pszVal );
RESULT STDCALL XML_ValueTrans( IN LPCSTR pszMsg, IN UINT nLen, OUT LPSTR pszVal );
RESULT STDCALL XML_GetInfoFromMsg( \
                          IN OUT LPSTR *ppszMsg, /*输入的节点的数据缓冲区,返回子节点的超始位置*/\
                          IN OUT UINT *pnMsgLen, /*输入缓冲区的长度,输出此节点数据体的长度*/\
                          OUT LPSTR pszName, /*节点名*/\
                          OUT LPSTR pszData, /*节点数据*/\
                          OUT PNODEPROPERTY pProp, /*节点的属性*/\
                          OUT BOOL *pbIsParent, /*是否有子节点*/\
                          OUT LPSTR *ppszNextNode /*下一节点的位置,如果返回为空,下一节点不存在*/\
                          );
void STDCALL TrimLast( IN OUT LPSTR pszStr );
void STDCALL TrimSpace( IN OUT LPSTR pszStr );
RESULT STDCALL GetPriorPath( IN LPCSTR pszPath, OUT LPSTR pszPriorPath );
RESULT STDCALL GetLastName( IN LPCSTR pszPath, OUT LPSTR pszName );
RESULT STDCALL GetLeavePath( IN LPCSTR pszPath, OUT LPSTR pszLeavePath );
RESULT STDCALL GetRootName( IN LPCSTR pszPath, OUT LPSTR pszName );
RESULT STDCALL MakeEndName( IN LPCSTR pszName, OUT LPSTR pszEndName );
UINT STDCALL Calu_Var_Chgs( IN LPCSTR pszData );
RESULT STDCALL XML_ConvertPath( IN LPCSTR pszPath, OUT LPSTR pszFormatPath, IN OUT UINT *pnFormatLen );
DWORD STDCALL Ustrlen( unsigned short *pnzStr );

/*-------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_AllocProperty( IN OUT PNODEPROPERTY pProp, IN UINT nPropertyCount )
{
    /*为节点分配属性内存*/
    UINT nSize;

    DETECT_NULL( pProp );
    if ( nPropertyCount  ) {
        nSize = nPropertyCount * sizeof( PROPER );
        ASSERT_NULL( pProp->pVal = ( PPROPER )AllocMemory( nSize ) );
    }
    pProp->nCount = nPropertyCount;

    return NORMAL;

}

/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_FreeProperty( IN OUT PNODEPROPERTY pProp )
{
    /*释放属性信息*/
    DETECT_NULL( pProp );
    DETECT_NULL( pProp->pVal );

    FreeMemory( ( LPVOID )pProp->pVal );

    /*置属性的值*/
    pProp->pVal = NULL;
    pProp->nCount = 0;

    return NORMAL;

}

/*-------------------------------------------------------------------------*/
PXMLNODE STDCALL XML_AllocNode( IN LPCSTR pszName, IN LPCSTR pszData, IN PCNODEPROPERTY pProp )
{
    /*为XML的节点分配内存*/
    PXMLNODE pNode;
    LPSTR pszInsData = NULL;

    /*判断节点名及数据的长度有效性*/
    if ( pszName != NULL ) {
        if ( !VERIFY( strlen( pszName ) <= XML_NAME_LEN ) ) {
            return NULL;
        }
    }

    /*判断值是否为空  ------>  ""是否为空串呢?*/
    if ( ( pszData != NULL ) && ( strlen( pszData ) > 0 ) ) {
        if ( VERIFY_NULL( pszInsData = ( LPSTR )AllocMemory( ( UINT )strlen( pszData ) + 3 ) ) )
            strcpy( pszInsData, pszData );
        else
            return NULL;

    }

    pNode = ( PXMLNODE )AllocMemory( sizeof( XMLNODE ) );

    if ( VERIFY_NULL( pNode ) ) {
        /*如果你输入一个为空的节点名或数据,
        那么新的节点名为空或节点数据为空。*/

        memset( pNode, 0, sizeof( XMLNODE ) );

        if ( pszName != NULL )
            strcpy( pNode->szName, pszName );
        else
            strcpy( pNode->szName, "<>" );

        pNode->pszData = pszInsData;

		/*置节点属性的值*/
		if ( pProp != NULL ) {
            if ( VERIFY_NORMAL( XML_AllocProperty( &( pNode->nProperty ), pProp->nCount ) ) ) {
                memcpy( pNode->nProperty.pVal, pProp->pVal, pProp->nCount * sizeof( PROPER ) );

			}

		}

        return pNode;

    }

    if ( pszInsData != NULL )
        FreeMemory( ( LPVOID )pszInsData );

    return NULL;

}
/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_FreeNode( IN PXMLNODE pNode )
{
    /*释放XML节点内存*/
    DETECT_NULL( pNode );

    XML_FreeProperty( &( pNode->nProperty ) );
    FreeMemory( ( LPVOID )pNode );

    return NORMAL;

}

/*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_Create( \
               IN OUT PXMLSTRUCT pXml, /*XML结构指针*/\
               IN LPCSTR pszName, /*XML根节点名*/\
               IN LPCSTR pszData, /*XML根节点的值*/\
               IN PCNODEPROPERTY pProp /*XML根节点的属性*/\
               )
{
    /*初始化XML结构及数据*/
    char szName[XML_NAME_LEN + 1];

    DETECT_NULL( pXml );

    DETECT( pszName == NULL || strlen( pszName ) <= XML_NAME_LEN );
    DETECT( pszData == NULL || ( strlen( pszData ) + Calu_Var_Chgs( pszData ) * 4 ) <= XML_DATA_LEN );

    /*置默认根节点*/
    if ( pszName == NULL || ( strlen( pszName ) == 0 ) ) {
        #ifndef _WIN32
        sprintf( szName, "<ROOT>" );
        #else
        wsprintf( szName, "<ROOT>" );
        #endif
    }
    else {
        ASSERT_NORMAL( GetRootName( pszName, szName ) );

    }

    XML_Delete( pXml );
    memset( pXml, 0, sizeof( XMLSTRUCT ) ); /*XML结构清零*/

    pXml->nMaxLen = 0x02000000; /*最大为32M的XML文件缓冲区*/
    TREE_Init( &(pXml->nTree) );

    ASSERT_NORMAL( XML_InsertRoot( pXml, ( LPCSTR )szName, pszData, pProp ) );

    nCharType = GB2312;    /*设置编码类型,默认为GB2312*/

    return NORMAL;

}

/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_Delete( IN OUT PXMLSTRUCT pXml )
{
    /*释放XML内存*/
    DETECT_NULL( pXml );
    if ( pXml->nTree.nRootPos != NULL ) XML_DelNodeByPos( pXml, pXml->nTree.nRootPos );

    return NORMAL;

}

/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_SetRootName( IN OUT PXMLSTRUCT pXml, IN LPCSTR pszName )
{
    /*设置XML的名字*/
    UINT nSize, nLen;
    char tmpName[33];
    PXMLNODE pNode;

    DETECT_NULL( pXml );
    DETECT_NULL( pXml->nTree.nRootPos );
    DETECT_NULL( pszName );
    DETECT( strlen( pszName ) > 0 );

    /*取根节点名*/
    ASSERT_NORMAL( GetRootName( pszName, tmpName ) );

    /*取根节点的值*/
    TREE_GetVal( &( pXml->nTree ), pXml->nTree.nRootPos, ( LPVOID * )&pNode );
    DETECT_NULL( pNode );

    /*测试长度*/
    nLen = ( UINT )strlen( tmpName );
    DETECT( nLen <= XML_NAME_LEN );

    nSize = ( UINT )strlen( pNode->szName );
    strcpy( pNode->szName, tmpName );

    /*更改XML的长度*/
    pXml->nLen += ( 2 * nLen - 2 * nSize );

    return NORMAL;

}

/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_GetRootName( IN PCXMLSTRUCT pXml, IN OUT LPSTR pszName, IN OUT UINT *pnNameLen )
{
    /*取根节点的节点名,如果pszName为NULL,则返回名字的长度*/
    PXMLNODE pNode;
    UINT nLen;

    DETECT_NULL( pXml );
    DETECT_NULL( pXml->nTree.nRootPos );

    /*取根节点的值*/
    TREE_GetVal( &( pXml->nTree ), pXml->nTree.nRootPos, ( LPVOID * )&pNode );
    DETECT_NULL( pNode );

    nLen = ( UINT )strlen( ( const char * )( pNode->szName ) );

    if ( pszName == NULL ) {
        *pnNameLen = nLen;
        return NORMAL;
    }

    DETECT( *pnNameLen > nLen );
    *pnNameLen = nLen;

    strcpy( pszName, pNode->szName );

    return NORMAL;

}

/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_SetRootProperty( IN OUT PXMLSTRUCT pXml, IN PCNODEPROPERTY pProp )
{
    /*设置根节点的属性*/
    PXMLNODE pNode;
    UINT nSize, nPropertySize, nLoop;

    DETECT_NULL( pXml );
    DETECT_NULL( pXml->nTree.nRootPos );

    /*取根节点的值*/
    TREE_GetVal( &( pXml->nTree ), pXml->nTree.nRootPos, ( LPVOID * )&pNode );
    DETECT_NULL( pNode );

    /*计算原属性的大小*/
    nSize = 0;
    for( nLoop = 0; nLoop < pNode->nProperty.nCount; nLoop ++ ) {
        nSize += ( UINT )( strlen( pNode->nProperty.pVal[nLoop].szName ) + 2 \
			+ strlen( pNode->nProperty.pVal[nLoop].szData ) \
            + Calu_Var_Chgs( pNode->nProperty.pVal[nLoop].szData ) * 4 + 2 );
    }

    XML_FreeProperty( &( pNode->nProperty ) );
    pXml->nLen -= nSize;

    if ( pProp != NULL ) {
        nPropertySize = 0;
        for( nLoop = 0; nLoop < pProp->nCount; nLoop ++ ) {
            nPropertySize += ( UINT )( strlen( pProp->pVal[nLoop].szName ) + 2 \
                + strlen( pProp->pVal[nLoop].szData ) \
                + Calu_Var_Chgs( pProp->pVal[nLoop].szData ) * 4 + 2 );

        }

        if ( pProp->nCount ) {
            ASSERT_NORMAL( XML_AllocProperty( &( pNode->nProperty ), pProp->nCount ) );
            memcpy( pNode->nProperty.pVal, pProp->pVal, pProp->nCount * sizeof( PROPER ) );
            pXml->nLen += nPropertySize;
        }

    }

    return NORMAL;

}

/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_GetRootProperty( IN PCXMLSTRUCT pXml, OUT PNODEPROPERTY pProp )
{
    /*取根节点的属性*/
    PXMLNODE pNode;

    DETECT_NULL( pXml );
    DETECT_NULL( pXml->nTree.nRootPos );

    /*取根节点的值*/
    TREE_GetVal( &( pXml->nTree ), pXml->nTree.nRootPos, ( LPVOID * )&pNode );
    DETECT_NULL( pNode );

    /*判断输出属性的指针是否有效*/
    DETECT_NULL( pProp );

    XML_FreeProperty( pProp );

    /*分配属性内存*/
    ASSERT_NORMAL( XML_AllocProperty( pProp, pNode->nProperty.nCount ) );
    memcpy( pProp->pVal, pNode->nProperty.pVal, pNode->nProperty.nCount * sizeof( PROPER ) );

    return NORMAL;

}

/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_DelNodeByPos( IN OUT PXMLSTRUCT pXml, IN POS nPos )
{
    /*按位置删除节点,此函数是一个递归函数*/
    POS nPosDel, nPosChild, nPosParent;
    PXMLNODE pNode;
    UINT nDataLen, nDepth, nProperLen, iLoop;

    /*有效性判断*/
    DETECT_NULL( pXml );
    DETECT( TREE_NodeIsValid( &( pXml->nTree ), nPos ) );

    /*先删除节点的子孙节点*/
    nPosChild = nPos;
    TREE_GetChildHead( &( pXml->nTree ), &nPosChild );

    while( nPosChild != NULL ) {
        nPosDel = nPosChild;
        TREE_GetNext( &( pXml->nTree ), &nPosChild );
        XML_DelNodeByPos( pXml, nPosDel );

    }

    TREE_GetVal( &( pXml->nTree ), nPos, ( LPVOID * )&pNode );

    /*对于空串的判断,可以在此处不修改*/
    nDataLen = ( pNode->pszData == NULL ) ? 0 : ( UINT )strlen( pNode->pszData ) + Calu_Var_Chgs( ( LPCSTR )( pNode->pszData ) ) * 4;
    nDepth = TREE_GetDepth( &pXml->nTree, nPos );

	/*计算属性的长度*/
	nProperLen = 0;
	
	for( iLoop = 0; iLoop < pNode->nProperty.nCount; iLoop ++ ) {
		nProperLen += ( UINT )( strlen( pNode->nProperty.pVal[iLoop].szName ) + 2 \
			+ strlen( pNode->nProperty.pVal[iLoop].szData ) \
            + Calu_Var_Chgs( pNode->nProperty.pVal[iLoop].szData ) * 4 + 2 );
	}

	/*计算XML的长度*/
    pXml->nLen -= ( ( UINT )( 2 * strlen( pNode->szName ) ) + 1 + nDataLen + nDepth + nProperLen );

    /*对其父节点的处理*/
    nPosParent = nPos;
    TREE_GetParent( &( pXml->nTree ), &nPosParent );

    /*如果是最后一个子节点*/
    if ( ( nPosParent != NULL ) && ( TREE_GetChildCount( &( pXml->nTree ), nPosParent ) == 1 ) )
        pXml->nLen -= ( nDepth - 1 );

    if ( pNode->pszData != NULL ) FreeMemory( ( LPVOID )pNode->pszData );

    /*删除节点*/
    XML_FreeNode( pNode );

    /*在树中删除节点*/
    TREE_DeleteNode( &( pXml->nTree ), nPos );

    return NORMAL;

}

/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_DeleteNode( IN OUT PXMLSTRUCT pXml, IN LPCSTR pszPath )
{
    /*在XML中删除第一个路径名为pszPath的节点*/
    POS nPos;

    DETECT_NULL( pXml );
    DETECT_NULL( pXml->nTree.nRootPos );

    DETECT_NULL( pszPath );
    DETECT( strlen( pszPath ) <= XML_PATH_LEN );

⌨️ 快捷键说明

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