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

📄 mxmltree.cpp

📁 跨平台C++基础库
💻 CPP
字号:

#include "MCRT/MXMLTree.h"

#include "MCRT/MXMLNode.h"
#include "tinyxml.h"

MXMLTree::MXMLTree()
:m_pDoc(NULL)
{
    m_encoding  =   "GB2312";
}

MXMLTree::~MXMLTree()
{
    delete this->m_pDoc;
}

MXMLTree* MXMLTree::Clone() const
{
    if ( ! this->IsValid() )
    {
        return NULL;
    }

    /* - Failed when use copy constructor of TiXmlDocument
    TiXmlDocument*  pCloneDoc   =   new TiXmlDocument( *(this->m_pDoc) );
    if ( pCloneDoc == NULL )
    {
        return NULL;
    }

    MXMLTree*   pClone  =   new MXMLTree;
    if ( pClone == NULL )
    {
        return NULL;
    }
    pClone->m_pDoc      =   pCloneDoc;
    pClone->m_rootNode  =   MXMLNode( pCloneDoc->RootElement() );
    */

    TiXmlDocument*  pCloneDoc   =   new TiXmlDocument;
    if ( pCloneDoc == NULL )
    {
        return NULL;
    }

    TiXmlNode*  pNode   =   this->m_pDoc->FirstChild();
    while ( pNode != NULL )
    {
        pCloneDoc->LinkEndChild( pNode->Clone() );

        pNode   =   pNode->NextSibling();
    }

    MXMLTree*   pClone  =  new MXMLTree;
    if ( pClone == NULL )
    {
        delete pCloneDoc;
        return NULL;
    }

    pClone->m_pDoc      =   pCloneDoc;
    pClone->m_rootNode  =   MXMLNode( pCloneDoc->RootElement() );

    return pClone;
}

const char* MXMLTree::GetEncoding()
{
    if ( this->IsValid() )
    {
        TiXmlNode*  pNode   =   this->m_pDoc->FirstChild();
        while ( pNode != NULL )
        {
            if ( pNode->Type() == TiXmlNode::DECLARATION )
            {
                this->m_encoding    =   pNode->ToDeclaration()->Encoding();

                break;
            }

            pNode   =   this->m_pDoc->NextSibling();
        }
    }

    return this->m_encoding.c_str();
}

void MXMLTree::SetEncoding( const std::string& strEncoding )
{
    this->m_encoding    =   strEncoding;
}

MXMLNode MXMLTree::GetRootNode()
{
    return this->m_rootNode;
}

MXMLNode MXMLTree::GetNode( const std::string& strNodePath, mInt32 index )
{
    if ( strNodePath.empty() || (strNodePath[0] != '/') || (strNodePath.length() == 1) )
    {
        return MXMLNode( NULL );
    }

    std::string::size_type  posBegin        =   1;
    std::string::size_type  posEnd          =   std::string::npos;
    std::string             strTmpNodePath  =   strNodePath;
    std::string             strNodeName;
    MXMLNode                node;
    const char*             pRootNodeName   =   NULL;

    std::string::size_type  lenPath =   strTmpNodePath.length();
    if ( strTmpNodePath[lenPath-1] == '/' )
    {
        strTmpNodePath.resize( lenPath - 1 );
    }

    //get root node name
    pRootNodeName   =   this->m_rootNode.GetName();
    if ( pRootNodeName == NULL )
    {
        pRootNodeName   =   "";
    }

    //check root path
    posEnd  =   strTmpNodePath.find_first_of( '/', posBegin );
    if ( posEnd != std::string::npos ) //get non-root path
    {
        strNodeName =   strTmpNodePath.substr( posBegin, posEnd - posBegin );
        if ( strNodeName != pRootNodeName )
        {
            return MXMLNode( NULL );
        }

        posBegin    =   posEnd + 1;
        node        =   this->m_rootNode;
        posEnd      =   strTmpNodePath.find_first_of( '/', posBegin );
    }
    else //get root path
    {
        if ( strTmpNodePath == pRootNodeName )
        {
            return this->m_rootNode;
        }
        else
        {
            return MXMLNode( NULL );
        }
    }

    while ( posEnd != std::string::npos )
    {
        strNodeName =   strTmpNodePath.substr( posBegin, posEnd - posBegin );
        node        =   node.GetChild( strNodeName );
        if ( ! node.IsValid() )
        {
            return MXMLNode( NULL );
        }

        posBegin        =   posEnd + 1;
        posEnd          =   strTmpNodePath.find_first_of( '/', posBegin );
    }

    strNodeName =   strTmpNodePath.substr( posBegin );
    node        =   node.GetChild( strNodeName, index );
    return node;
}

void MXMLTree::SetRootNode( const MXMLNode& rootNode )
{
    if ( rootNode.IsValid() )
    {
        this->m_rootNode    =   rootNode;
    }
}

bool MXMLTree::Load( const std::string& strXMLFile )
{
    bool    bLoaded =   false;

    //release old before load new
    if ( this->m_pDoc != NULL )
    {
        delete this->m_pDoc;

        this->m_pDoc        =   NULL;
    }

    // replace EXIT_FUNCTION with do{} while(false)
    do
    {
        this->m_pDoc    =   new TiXmlDocument( strXMLFile.c_str() );
        if ( this->m_pDoc == NULL )
        {
            break;
        }
        if ( ! this->m_pDoc->LoadFile() )
        {
            break;
        }

        this->m_rootNode.m_pMXMLNodeImpl    =   this->m_pDoc->RootElement();
        if ( ! this->m_rootNode.IsValid() )
        {
            break;
        }

        bLoaded =   true;
    } while( false );


    if ( ! bLoaded )
    {
        delete this->m_pDoc;

        this->m_pDoc        =   NULL;
    }
    return bLoaded;
}

bool MXMLTree::Save( const std::string& strXMLFile )
{
    bool    bSaved  =   true;

    for ( int iOnce = 0; iOnce < 1; ++ iOnce ) // convenient for releasing resources while failed
    {
        bSaved  =   this->IsValid();
        if ( ! bSaved )
        {
            break;
        }

        if ( this->m_pDoc == NULL ) //if new, load XML info and root node
        {
            this->m_pDoc    =   new TiXmlDocument;
            if ( this->m_pDoc == NULL )
            {
                bSaved  =   false;
                break;
            }

            this->m_pDoc->LinkEndChild( new TiXmlDeclaration( "1.0", this->m_encoding.c_str(), "" ) );

            this->m_pDoc->LinkEndChild( this->m_rootNode.m_pMXMLNodeImpl );
        }

        this->m_pDoc->SaveFile( strXMLFile.c_str() );
    }

    return bSaved;
}

bool MXMLTree::IsValid() const
{
    return this->m_rootNode.IsValid();
}

⌨️ 快捷键说明

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