XML解析器接口–C++版

Resource.h文件

/*Resource.h*/

//{{NO_DEPENDENCIES}}

//Microsoft Visual C++ generated include file.

//Used by XMLParseInterface.RC

//新对象的下一组默认值

#ifdef APSTUDIO_INVOKED

#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NEXT_RESOURCE_VALUE    3000

#define _APS_NEXT_CONTROL_VALUE     3000

#define _APS_NEXT_SYMED_VALUE       3000

#define _APS_NEXT_COMMAND_VALUE     32771

#endif

#endif

XMLParseInterface.h文件

XMLPARSEINTERFACE_EXPORTS

#ifdef XMLPARSEINTERFACE_EXPORTS

#define XMLPARSEINTERFACE_API __declspec(dllexport)

#else

#define XMLPARSEINTERFACE_API __declspec(dllimport)

#endif

#include

#include

#include

#include

class XMLPARSEINTERFACE_API CXMLObject

{

public:

    //!得到节点名字

    /*!

    *   /return             返回该节点的名字

    */

    CString  GetNodeName() const;

    //!得到节点深度

    /*!

    *   /return             返回该节点的深度

    */

    int  GetLevel() const;

    //!得到父节点对象

    /*!

    *   /return             返回该节点的父节点对象

    */

    CXMLObject * GetParent() const;

    //!得到属性列表中指定索引的属性

    /*!

    *   /param  iIndex                  指定的索引-输入参数

    *   /param  szAttributeValue        属性-输出参数

    *   /return                         如果找到则返回该TRUE,否则返回FALSE

    */

    bool GetAttributeOnIndex( int iIndex , CString & szAttributeValue) const;

    //!得到属性列表中属性的个数

    /*!

    *   /return             返回属性个数

    */

    int GetAttributeCount() const;

    //!查找指定属性名称的属性值

    /*!

    *   /param  szAttributeName                 指定的属性名称-输入参数

    *   /param  szAttributeValue                属性-输出参数

    *   /return                                 如果找到则返回该TRUE,否则返回FALSE

    */

    bool FindAttribute( const CString & szAttributeName, CString & szAttributeValue ) const;

    //!查找指定索引处的子节点对象

    /*!

    *   /param  iIndex                  指定的索引-输入参数

    *   /return                         返回指定索引的孩子节点对象

    */

    CXMLObject * GetChildOnIndex( int iIndex );

    const CXMLObject * GetChildOnIndex( int iIndex )const;

    //!得到孩子节点个数

    /*!

    *   /return             返回孩子节点个数

    */

    int GetChildrenCount() const;

    //!祖先关系判断

    /*!

    *   /param  pParant                 假设的祖先节点-输入参数

    *   /return                         如果确实是该节点的祖先返回TRUE,否则返回FALSE

    */

    bool IsPosterityOf( CXMLObject * pParant );

    //!是否叶子

    /*!

    *   /return                         如果是叶子节点返回TRUE,否则返回FALSE

    */

    bool IsLeaf() const;

private:

    //友元类声明

    friend class CXMLStructBuilder;

private:

    //!构造函数

    /*!

    *   /param  szNmae                  节点名字-输入参数

    *   /param  iLevel                  节点深度-输入参数

    *   /param  pParant                 节点的父节点-输入参数

    */

    CXMLObject( const CString & szNmae, int iLevel , CXMLObject * pParant = NULL);

    //!析构函数

    ~CXMLObject();

    //!线索化

    /*!

    *   /param  io_pPre                 线索指针-输入输出参数

    *   /return                         如果成功返回TRUE,否则返回FALSE

    */

    bool Threaded_Preorder( CXMLObject ** & io_pPre );

    //!加入属性

    /*!

    *   /param  szAttributeName                 属性名字-输入参数

    *   /param  szAttributeValue                属性值-输入参数

    *   /return                                 void

    */

    void AddAttribute( const CString & szAttributeName, const CString & szAttributeValue );

    //!加入孩子节点

    /*!

    *   /param  pChild                  要加入的孩子节点-输入参数

    *   /return                         void

    */

    void AddChild( CXMLObject * pChild );

    //!销毁所有孩子节点

    /*!

    *   /return                         void

    */

    void DestroyChildren();

private:

    /*线索化指针*/

    CXMLObject * m_pThreaded_Preorder;

    /*节点名字*/

    CString m_szName;

    /*保存此节点深度*/

    int m_iLevel;

    /*保存父亲节点指针*/

    CXMLObject * m_pParent;

    /*孩子节点链表*/

    CArray< CXMLObject *, CXMLObject * > m_aChildren;

    /*为了安顺序查找属性*/

    CArray< CString ,CString  > m_strAttr;

    /*属性表*/

    CMapStringToString m_AttrMap;

};

class XMLPARSEINTERFACE_API CXMLStructBuilder

{

public:

    //!构造函数

    /*!

    *   /param  pszLocalAddr    本地绑定地址

    *   /param  uLocalPort      本地绑定端口

    *   /return                 如果创建成功返回true,否则返回false

    */

    CXMLStructBuilder();

    //!建立结构树

    /*!

    *   /param  szPath  XML文件的路径-输入参数

    *   /param  pRoot   根元素节点对象-输出参数

    *   /return         如果创建成功返回true,否则返回false

    */

    bool BuildTree( const CString & szPath , CXMLObject * &pRoot );

    //!查找命名节点对象

    /*!

    *   /param  szName      节点名称-输入参数

    *   /param  pStartNode  指定开始查找的位置-输入参数

    *   /return             如果找到则返回该对象,否则返回NULL

    */

    CXMLObject * FindNamedNode( const CString & szName , CXMLObject * pStartNode );

    //!查找命名子节点对象

    /*!

    *   /param  szName      节点名称-输入参数

    *   /param  pStartNode  指定开始查找的位置-输入参数

    *   /param  pParant     父节点对象,找到的结果必须是pParant的子节点-输入参数

    *   /return             如果找到则返回该对象,否则返回NULL

    */

    CXMLObject * FindNamedSubNode( const CString & szName ,CXMLObject * pStartNode , CXMLObject * pParant );

    //!查找命名同级节点对象

    /*!

    *   /param  szName      节点名称-输入参数

    *   /param  pStartNode  指定开始查找的位置-输入参数

    *   /param  iLevel      指定的深度,找到的结果的节点深度必须为iLevel-输入参数

    *   /return             如果找到则返回该对象,否则返回NULL

    */

    CXMLObject * FindNamedLevelNode( const CString & szName , CXMLObject * pStartNode ,int iLevel );

    //!销毁结构树

    void DestroyTree();

public:

    //!析构函数

    ~CXMLStructBuilder();

private:

    //!创建结构树节点对象

    /*!

    *   /param  pRoot       IXMLDOMNode节点对象-输入参数

    *   /param  iLevel      指定的深度-输入参数

    *   /param  pParant     构造结果的父节点-输入参数

    *   /return             如果找到则返回该TRUE,否则返回FALSE

    */

    bool BuildXMLObject( IXMLDOMNode *  pRoot , int iLevel , CXMLObject * pParant );

    //!创建结构树节点对象

    /*!

    *   /param  pNode       IXMLDOMNode节点对象-输入参数

    *   /param  pParant     CXMLObject节点对象-输入参数

    *   /return             如果找到则返回该TRUE,否则返回FALSE

    */

    bool BuildAttribute( IXMLDOMNode * pNode , CXMLObject * pParant );

private:

    /*根节点对象*/

    CXMLObject * m_pXmlTreeRoot;//=NULL;

};

XMLParseInterface.cpp文件

#include "stdafx.h"

#include

#include "XMLParseInterface.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

static AFX_EXTENSION_MODULE XMLParseInterfaceDLL = { NULL, NULL };

#ifdef _MANAGED

#pragma managed(push, off)

#endif

extern "C" int APIENTRY

DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)

{

    // 如果使用 lpReserved,请将此移除

    UNREFERENCED_PARAMETER(lpReserved);

    if (dwReason == DLL_PROCESS_ATTACH)

    {

        TRACE0("XMLParseInterface.DLL 正在初始化!/n");      

        // 扩展 DLL 一次性初始化

        if (!AfxInitExtensionModule(XMLParseInterfaceDLL, hInstance))

            return 0;

        // 将此 DLL 插入到资源链中

        // 注意: 如果此扩展 DLL 由

        //  MFC 规则 DLL (如 ActiveX 控件)隐式链接到,

        //  而不是由 MFC 应用程序链接到,则需要

        //  将此行从 DllMain 中移除并将其放置在一个

        //  从此扩展 DLL 导出的单独的函数中。使用此扩展 DLL 的

        //  规则 DLL 然后应显式

        //  调用该函数以初始化此扩展 DLL。否则,

        //  CDynLinkLibrary 对象不会附加到

        //  规则 DLL 的资源链,并将导致严重的

        //  问题。

        new CDynLinkLibrary(XMLParseInterfaceDLL);

    }

    else if (dwReason == DLL_PROCESS_DETACH)

    {

        TRACE0("XMLParseInterface.DLL 正在终止!/n");

        // 在调用析构函数之前终止该库

        AfxTermExtensionModule(XMLParseInterfaceDLL);

    }

    return 1;   // 确定

}

#ifdef _MANAGED

#pragma managed(pop)

#endif

CXMLObject::CXMLObject( const CString & szNmae, int iLevel, CXMLObject * pParant )

{

    m_szName = szNmae;

    m_iLevel = iLevel;

    m_pParent = pParant;

}

CXMLObject::~CXMLObject()

{

    DestroyChildren();

}

void CXMLObject::AddAttribute( const CString & szAttributeName, const CString & szAttributeValue )

{

    m_AttrMap.SetAt( szAttributeName , szAttributeValue );

    m_strAttr.Add( szAttributeName );

}

void CXMLObject::AddChild( CXMLObject * pChild )

{

    m_aChildren.Add( pChild );

}

bool CXMLObject::FindAttribute( const CString & szAttributeName , CString & szAttributeValue ) const

{

    if( m_AttrMap.Lookup( szAttributeName , szAttributeValue ) )

        return true;

    return false;

}

CString CXMLObject::GetNodeName() const

{

    return m_szName;

}

int CXMLObject::GetLevel() const

{

    return m_iLevel;

}

CXMLObject * CXMLObject::GetParent() const

{

    if ( m_iLevel == 0 )

    {

        return NULL;

    }

    return m_pParent;

}

bool CXMLObject::GetAttributeOnIndex( int iIndex, CString & szAttributeValue )  const

{

    int iSize = GetAttributeCount();

    for (int i = 0; i < iSize; i++ )

    {

        if( i == iIndex )

        {

            this -> FindAttribute ( m_strAttr.ElementAt( i ) , szAttributeValue );

            return true;

        }

    }

    return false;

}

int CXMLObject::GetAttributeCount() const

{

    return m_AttrMap.GetSize();

}

bool CXMLObject::IsLeaf() const

{

    if( m_aChildren.IsEmpty() )

        return true;

    return false;

}

CXMLObject * CXMLObject::GetChildOnIndex( int iIndex )

{

    CXMLObject * pChild = NULL;

    pChild = m_aChildren.ElementAt( iIndex );

    if( pChild != NULL )

        return pChild;

    return NULL;

}

const CXMLObject * CXMLObject::GetChildOnIndex( int iIndex ) const

{

    CXMLObject * pChildI = NULL;

    pChildI = m_aChildren.ElementAt( iIndex );

    if( pChildI != NULL )

        return pChildI;

    return NULL;

}

int CXMLObject::GetChildrenCount() const

{

    return m_aChildren.GetSize();

}

void CXMLObject::DestroyChildren()

{

    for(int i = 0;i < m_aChildren.GetSize(); i++ )

        delete m_aChildren.ElementAt( i );

    m_aChildren.RemoveAll();

}

bool CXMLObject::IsPosterityOf( CXMLObject * pParant )

{

    CXMLObject * pAncestor = this -> m_pParent;

    do

    {

        if ( pAncestor == pParant )

        {

            return true;

        }

        pAncestor = pAncestor -> m_pParent;

    }while( pAncestor );

    return false;

}

bool CXMLObject::Threaded_Preorder( CXMLObject ** & io_pPre )

{

    if( !io_pPre )

    {

        return false;

    }

    m_pThreaded_Preorder = NULL;    //!清空,防止重复调用线性化算法时发生错误

    ( *io_pPre ) = this;

    io_pPre = &m_pThreaded_Preorder;

    int iArrayCount=GetChildrenCount();

    for( int i = 0;i < iArrayCount; i++ )

    {

        if( !( m_aChildren.ElementAt( i) -> Threaded_Preorder( io_pPre ) ) )

        {

            return false;

        }

    }

    return true;

}

CXMLStructBuilder::CXMLStructBuilder()

{

    m_pXmlTreeRoot=NULL;

}

CXMLStructBuilder::~CXMLStructBuilder()

{

    delete m_pXmlTreeRoot;

}

bool CXMLStructBuilder::BuildTree( const CString & szPath , CXMLObject * & pRoot )

{

    bool bSucc = false;

    try

    {

        if( m_pXmlTreeRoot != NULL )

            DestroyTree();

        HRESULT hr;

        if( !szPath.IsEmpty() )

        {

            if( SUCCEEDED( CoInitialize( NULL ) ) )

            {

                IXMLDOMDocument * pDoc = NULL;

                hr = CoCreateInstance( CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument,( void ** )( &pDoc ) );

                if( SUCCEEDED( hr ) )

                {

                    if( SUCCEEDED( pDoc -> put_async( VARIANT_FALSE ) ) )

                    {

                        CComVariant cvFileName( szPath );

                        VARIANT_BOOL vBool;

                        hr = pDoc -> load( cvFileName, &vBool );

                        if( vBool == VARIANT_TRUE )

                        {

                            IXMLDOMNode * pXMLRootNode = NULL;

                            if( SUCCEEDED( pDoc -> QueryInterface( IID_IXMLDOMNode, reinterpret_cast< void** >( &pXMLRootNode ) ) ) )

                            {

                                BSTR bstr;

                                if( FAILED( pXMLRootNode->get_nodeName( &bstr ) ) )

                                {

                                    return false;

                                }

                                CString cstr;

                                cstr = bstr;

                                SysFreeString( bstr );

                                m_pXmlTreeRoot = new CXMLObject( cstr,0 );

                                pRoot = m_pXmlTreeRoot;

                                BuildXMLObject( pXMLRootNode , 1 , m_pXmlTreeRoot );

                                CXMLObject ** pre = &m_pXmlTreeRoot;

                                m_pXmlTreeRoot -> Threaded_Preorder( pre );

                                pXMLRootNode -> Release();

                                pXMLRootNode = NULL;

                                bSucc = true;

                            }

                        }

                    }

                    pDoc -> Release();

                    pDoc = NULL;

                }

                CoUninitialize();

            }

        }

    }

    catch( ... )

    {

        return false;

    }

    return bSucc;

}

void CXMLStructBuilder::DestroyTree()

{

    if( m_pXmlTreeRoot != NULL )

    {

        delete m_pXmlTreeRoot;

        m_pXmlTreeRoot = NULL;

    }

}

bool CXMLStructBuilder::BuildXMLObject( IXMLDOMNode *  pRoot , int iLevel , CXMLObject * pParant )

{

    try

    {

        if( !pRoot )

        {

            return false;

        }

        DOMNodeType NodeType;

        if( FAILED( pRoot -> get_nodeType( &NodeType ) ) )

        {

            return false;

        }

        switch( NodeType )

        {

        case NODE_COMMENT:

            return true;

        default:

            break;

        }

        BSTR bstr;

        if( FAILED( pRoot -> get_nodeName( &bstr ) ) )

        {

            return false;

        }

        CString cstr( bstr );

        SysFreeString( bstr );

        CXMLObject * pChildNode = NULL;

        pChildNode = new CXMLObject( cstr,iLevel,pParant );

        if( !pChildNode )

        {

            return false;

        }

        pParant -> AddChild( pChildNode );

        BuildAttribute( pRoot, pChildNode );

        IXMLDOMNodeList * pXMLChildNodeList = NULL;

        if( FAILED( pRoot -> get_childNodes( &pXMLChildNodeList ) ) )

        {

            return false;

        }

        IXMLDOMNode * pXMLChildNode = NULL;

        long lNodeCount = 0;

        pXMLChildNodeList -> get_length( &lNodeCount );

        for( long j = 0; j < lNodeCount; ++j )

        {

            if( FAILED( pXMLChildNodeList->get_item( j, &pXMLChildNode ) ) )

            {

                pXMLChildNodeList -> Release();

                pXMLChildNodeList = NULL;

                return false;

            }

            if( !BuildXMLObject( pXMLChildNode,iLevel+1, pChildNode ) )

            {

                pXMLChildNode -> Release();

                pXMLChildNode = NULL;

                pXMLChildNodeList -> Release();

                pXMLChildNodeList = NULL;

                return false;

            }

            pXMLChildNode -> Release();

            pXMLChildNode = NULL;

        }

        pXMLChildNodeList -> Release();

        pXMLChildNodeList = NULL;

    }

    catch( ... )

    {

        return false;

    }

    return true;

}

bool CXMLStructBuilder::BuildAttribute( IXMLDOMNode * pNode , CXMLObject * pThis )

{

    try

    {

        IXMLDOMNamedNodeMap * pXMLNodeMap = NULL;

        if( FAILED( pNode -> get_attributes( &pXMLNodeMap ) ) )

        {

            return false;

        }

        if( pXMLNodeMap )

        {

            IXMLDOMNode * pXMLAttributeNode = NULL;

            long lAttributeCount = 0;

            pXMLNodeMap -> get_length( &lAttributeCount );

            for( long i = 0; i < lAttributeCount; ++i )

            {

                if( FAILED( pXMLNodeMap -> nextNode( &pXMLAttributeNode ) ) )

                {

                    pXMLNodeMap -> Release();

                    pXMLNodeMap = NULL;

                    return false;

                }

                BSTR bstrName;

                CString cstrName;

                if( FAILED( pXMLAttributeNode -> get_nodeName( &bstrName ) ) )

                {

                    pXMLAttributeNode -> Release();

                    pXMLAttributeNode = NULL;

                    pXMLNodeMap -> Release();

                    pXMLNodeMap = NULL;

                    return false;

                }

                cstrName = bstrName;

                SysFreeString( bstrName );

                VARIANT vstrValue;

                if( FAILED( pXMLAttributeNode -> get_nodeValue( &vstrValue ) ) )

                {

                    pXMLAttributeNode -> Release();

                    pXMLAttributeNode = NULL;

                    pXMLNodeMap -> Release();

                    pXMLNodeMap = NULL;

                    return false;

                }

                CString cstrValue;

                cstrValue = vstrValue;

                VariantClear( &vstrValue );

                pThis -> AddAttribute( cstrName, cstrValue );

                pXMLAttributeNode -> Release();

                pXMLAttributeNode = NULL;

            }

            pXMLNodeMap -> Release();

            pXMLNodeMap = NULL;

        }

    }

    catch( ... )

    {

        return false;

    }

    return true;

}

CXMLObject* CXMLStructBuilder::FindNamedNode( const CString & szNodeName,CXMLObject * pStartNode )

{

    CXMLObject * pRoot = pStartNode;

    pRoot = pRoot -> m_pThreaded_Preorder;

    while ( pRoot != NULL )

    {

        if ( pRoot -> GetNodeName().Compare( szNodeName ) == 0 )

        {

            return pRoot;

        }

        pRoot = pRoot -> m_pThreaded_Preorder;

    }

    return NULL;   

}

CXMLObject * CXMLStructBuilder::FindNamedSubNode( const CString & szName,CXMLObject * pStartNode,CXMLObject * pParant )

{

    CXMLObject * pRoot = pStartNode;

    pRoot = pRoot -> m_pThreaded_Preorder;

    while ( pRoot != NULL )

    {

        if( pRoot -> GetLevel() <= pParant -> GetLevel() )

            break;

        if ( ( pRoot -> GetNodeName().Compare( szName ) == 0) && ( pRoot -> IsPosterityOf( pParant ) ) )

        {

            return pRoot;

        }

        pRoot = pRoot -> m_pThreaded_Preorder;

    }

    return NULL;

}

CXMLObject * CXMLStructBuilder::FindNamedLevelNode( const CString & szName ,CXMLObject * pStartNode,int iLevel )

{

    CXMLObject * pRoot = pStartNode;

    pRoot = pRoot -> m_pThreaded_Preorder;

    while (pRoot != NULL)

    {

        if((pRoot -> GetLevel() == iLevel ) && ( pRoot -> GetNodeName().Compare( szName )==0 ) )

        {

            return pRoot;

        }

        pRoot = pRoot -> m_pThreaded_Preorder;

    }

    return NULL;

}

原文链接: https://blog.csdn.net/dog250/article/details/5303362

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    XML解析器接口--C++版

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/410352

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月26日 上午11:58
下一篇 2023年4月26日 上午11:58

相关推荐