📄 mxmltree.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 + -